WebLLM 如何用 enable_latency_breakdown 采集逐 token 采样延迟分解统计?

发布时间:2026/9/14 15:00:17
WebLLM 如何用 enable_latency_breakdown 采集逐 token 采样延迟分解统计? WebLLM 如何用 enable_latency_breakdown 采集逐 token 采样延迟分解统计【免费下载链接】web-llmHigh-performance In-browser LLM Inference Engine项目地址: https://gitcode.com/GitHub_Trending/we/web-llm在浏览器里跑 LLM 推理时decode 阶段的耗时往往不止模型前向本身logit 处理器、logit_bias、各类 penalty、结构化输出的 grammar bitmask 等后处理都可能影响每个 token 的生成速度。要定位耗时来源需要分阶段的逐 token 计时数据。WebLLMmlc-ai/web-llm提供了extra_body.enable_latency_breakdown请求参数置为true后响应的usage.extra.latencyBreakdown会返回六个阶段各自的时间数组单位秒数组中每个元素对应一个已生成的 token。示例工程 examples/get-started-latency-breakdown 基于mlc-ai/web-llm^0.2.84见 package.json加载Qwen3-0.6B-q0f32-MLC模型演示了完整采集流程。latencyBreakdown 的六个字段分别何时被采集LatencyBreakdown类型定义在 src/types.ts六个字段全部是number[]字段覆盖的采样阶段被填充的条件见 src/llm_chat.ts 的逐 token 循环grammarBitmaskTime获取 grammar bitmask 并在 GPU 上施加仅当请求使用 grammar 约束的response_formatjson_object/grammar/structural_taglogitProcessorTime在 CPU 上运行注册的 logit processor仅当引擎注册了 logit processorlogitBiasTime在 GPU 上施加logit_bias仅当请求设置了logit_biaspenaltyTime在 GPU 上施加 frequency/presence/repetition penalty仅当三类 penalty 任一非默认值且已有出现过 token 的记录sampleTime温度缩放 softmax、top-p 采样等采样步骤每个 decode token 都记录totalTime整个输出 token 步骤从步骤开始到采样完成每个 decode token 都记录也就是说sampleTime和totalTime的数组长度与本次生成的 token 数一致其余四个字段的数组只有在对应阶段实际执行时才会有元素。这一点决定了验证方式如果某个阶段数组为空先确认该阶段在当前请求下是否满足触发条件而不是怀疑统计出错。启用采集请求参数enable_latency_breakdown位于extra_body下属于 WebLLM 特有字段不在标准 OpenAI 接口中类型注释明确标注 Fields specific to WebLLM, not present in OpenAI见 src/openai_api_protocols/chat_completion.ts。非流式请求的完整启用方式const reply await engine.chat.completions.create({ messages: [{ role: user, content: List twenty US states. }], temperature: 0, max_tokens: 2048, extra_body: { enable_latency_breakdown: true }, }); // 采集结果挂在 usage.extra.latencyBreakdown各字段为 number[]秒 console.log(reply.usage?.extra?.latencyBreakdown);引擎侧只在request.extra_body?.enable_latency_breakdown为真时才会把统计写入响应否则latencyBreakdown为undefined见 src/engine.ts。docs/user/api_reference.rst 也将其列为 OpenAI 风格请求的扩展特性之一说明它会直通引擎并在底层支持时暴露增强遥测。快速路径运行仓库示例examples/get-started-latency-breakdown 是一个最小演示20 次重复同一请求把每次的usage.extra.latencyBreakdown逐字段聚合再计算avg/min/max/p99最后打印到浏览器 console。在该目录下执行npm install npm startnpm start实际执行parcel src/get_started_latency_breakdown.html --port 8888见 package.json在 8888 端口启动页面。打开页面后按示例 HTML 的提示Open console to see output在浏览器开发者工具的控制台中查看输出示例会打印Latency stats:—— 各阶段的 avg/min/max/p99示例结果数值随你的硬件与网络变化Decode tokens per second:、Completion tokens:、E2E latency (s):、Time per output token (s):—— 来自usage.extra的decode_tokens_per_s、completion_tokens、e2e_latency_s、time_per_output_token_s。有一个需要注意的出入示例文件 get_started_latency_breakdown.ts 里的请求对象没有显式传入extra_body: { enable_latency_breakdown: true }而引擎代码要求该标志为真才会返回latencyBreakdown。因此把这段代码搬到自己项目时务必自行补上这个字段否则聚合出来的latencyStats会是空对象。在自己的代码中采集并汇总统计示例的完整流程是创建引擎 → 多轮请求采集 → 逐阶段计算分位数统计。核心代码摘录自 get_started_latency_breakdown.tsextra_body字段为启用采集所必需已按上节说明补入请求import * as webllm from mlc-ai/web-llm; type LatencyBreakdown { logitProcessorTime: number[]; logitBiasTime: number[]; penaltyTime: number[]; sampleTime: number[]; totalTime: number[]; grammarBitmaskTime: number[]; }; async function main() { const selectedModel Qwen3-0.6B-q0f32-MLC; const engine: webllm.MLCEngineInterface await webllm.CreateMLCEngine( selectedModel, { logLevel: INFO }, { context_window_size: 2048 }, ); const latencyBreakdown: LatencyBreakdown { logitProcessorTime: [], logitBiasTime: [], penaltyTime: [], sampleTime: [], totalTime: [], grammarBitmaskTime: [], }; const numTrials 20; for (let i 0; i numTrials; i) { const reply await engine.chat.completions.create({ messages: [{ role: user, content: List twenty US states. }], temperature: 0, max_tokens: 2048, frequency_penalty: 1.2, presence_penalty: 1.0, repetition_penalty: 1.1, extra_body: { enable_latency_breakdown: true }, }); latencyBreakdown.logitProcessorTime.push(...(reply.usage?.extra.latencyBreakdown?.logitProcessorTime || [])); latencyBreakdown.logitBiasTime.push(...(reply.usage?.extra.latencyBreakdown?.logitBiasTime || [])); latencyBreakdown.penaltyTime.push(...(reply.usage?.extra.latencyBreakdown?.penaltyTime || [])); latencyBreakdown.sampleTime.push(...(reply.usage?.extra.latencyBreakdown?.sampleTime || [])); latencyBreakdown.totalTime.push(...(reply.usage?.extra.latencyBreakdown?.totalTime || [])); latencyBreakdown.grammarBitmaskTime.push(...(reply.usage?.extra.latencyBreakdown?.grammarBitmaskTime || [])); } // 每阶段计算 avg/min/max/p99 function _computeStats(arr: number[]) { if (!arr.length) return undefined; const sorted [...arr].sort((a, b) a - b); const avg arr.reduce((a, b) a b, 0) / arr.length; return { avg, min: sorted[0], max: sorted[sorted.length - 1], p99: sorted[Math.floor(0.99 * (sorted.length - 1))] }; } const latencyStats: Recordstring, any {}; for (const key of Object.keys(latencyBreakdown)) { const arr latencyBreakdown[key]; if (arr.length 0) latencyStats[key] _computeStats(arr); } console.log(Latency stats: , latencyStats); } main();示例中对 penalty 三个参数都取非默认值frequency_penalty: 1.2、presence_penalty: 1.0、repetition_penalty: 1.1因此penaltyTime数组会有数据如果你只想测纯采样耗时可以去掉这些参数对应数组随之为空这属于正常现象而非缺陷。流式请求通过 usage chunk 获取上面的路径针对非流式响应。流式场景下引擎在stream_options.include_usage为真时发送的 usage chunk 里同样携带latencyBreakdown见 src/engine.tsconst chunks await engine.chat.completions.create({ messages: [{ role: user, content: List twenty US states. }], stream: true, stream_options: { include_usage: true }, extra_body: { enable_latency_breakdown: true }, });在遍历 chunk 时从末尾 usage chunk 的usage.extra.latencyBreakdown读取字段含义与非流式一致。结果验证与限制成功条件reply.usage.extra.latencyBreakdown不是undefined且sampleTime、totalTime数组长度等于本次生成的 token 数usage.completion_tokens。usage.extra中的decode_tokens_per_s、time_per_output_token_s、e2e_latency_s可与totalTime数组交叉对照。标志为假的输出请求未设置enable_latency_breakdown时latencyBreakdown字段不存在——排查统计为空时先确认请求参数。阶段数组为空的解释按上表条件判断该阶段是否执行过例如不使用response_format的 grammar 输出时grammarBitmaskTime恒为空。数值性质所有数组元素单位均为秒是实测计时基于performance.now()而非估算分位数统计由你自己对多次、多 token 的数据计算文档不承诺固定数值。字段范围enable_latency_breakdown是extra_body下的 WebLLM 扩展参数不能写进标准 OpenAI 客户端的参数位置。【免费下载链接】web-llmHigh-performance In-browser LLM Inference Engine项目地址: https://gitcode.com/GitHub_Trending/we/web-llm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询