
作者卢建晖 - 微软高级云技术布道师排版Alan Wang改变对话的那个数字大多数关于“本地运行大语言模型”的教程都会从模型本身讲起。而这篇文章将从一张账单开始。云端大模型生成的每一个 Token 都需要计费。单次请求的成本或许微不足道但智能体从来不会只发起一次请求——它们会不断循环调用、反复重试并在每一天为每一位用户执行成千上万次请求。一个成功 AI 功能的成本曲线并不是平缓的而是会随着用户规模的增长不断上升。让产品变得受欢迎的因素往往也是让它变得昂贵的原因。这正是Token 经济学背后那个令人无法回避的现实在云端智能的边际成本永远不会降为零。只要功能还在运行你就需要按照 Token 数量持续为智能付费。而边缘侧推理则彻底改变了这个公式。当模型运行在用户已经拥有的硬件设备上时下一个 Token 的边际成本会逐渐趋近于零。你只需为硬件——也就是芯片——支付一次固定成本之后便可以持续生成任意数量的 Token。对于聊天助手、文本摘要、分类器、设备端 Copilot 等一大类应用场景而言这意味着一种从根本上不同的成本模型。也正因如此“推理究竟应该运行在哪里”正悄然成为今年最重要的架构决策之一。为了让这些概念更加具体本文将围绕一个真实可运行的开源项目展开kinfey/winml-qwen3-chat。该项目基于 Windows ML CLI将Qwen3-0.6B部署到 Windows NPU 上运行并与 CPU 推理进行性能对比测试同时提供一个桌面聊天应用实现逐 Token 流式输出的完整体验。为什么选择边缘侧而不仅仅是为了节省成本成本是最容易被看到的优势但这并不是全部。当推理从云端迁移到设备本地时你实际上一次性获得了四项关键收益成本。每个新增 Token 的边际成本趋近于零。无需按请求计费也不会因为某个功能突然爆火而收到意料之外的云服务账单。延迟。无需经过网络往返。模型距离应用只有一次函数调用的距离而不再是一次 HTTPS 请求的距离。对于交互式聊天场景而言这正是“响应迅速”和“加载转圈”之间的区别。隐私。提示词和数据始终保留在本地设备上。对于受监管数据、个人文档或者任何用户不愿上传到公共云端的信息来说“数据从未离开这台电脑”是能够提供的最强隐私保障。可用性。即使在飞机上、隧道中、企业防火墙后甚至云服务发生故障时应用依然能够正常运行。离线不再是一种降级模式而是默认运行模式。然而长期以来的难点在于**CPU 并不擅长这项工作。**通用 CPU 执行 Transformer 模型前向推理不仅速度较慢而且延迟波动明显。当操作系统不断调度核心资源时推理时间也会随之抖动。这正是专用 AI 芯片登场的原因。NPU为模型推理而生的处理器现代 AI PC 通常拥有三类计算单元而 Windows ML 为它们分别提供了对应的执行提供程序计算单元参考硬件Snapdragon X Elite执行提供程序NPUQualcomm Hexagon NPUX1E80100QNNExecutionProviderGPUQualcomm Adreno X1-85DmlExecutionProviderCPUSnapdragon X 12 核 3.40 GHzCPUExecutionProviderNPUNeural Processing Unit神经网络处理器并不是“更快的 CPU”。它是一种完全不同类型的处理器专门为一个任务而设计执行模型推理过程中大量且重复的矩阵乘法运算。CPU 是一个能力全面的通才而 NPU 则是高度专业化的专家。它能够以更高吞吐量、更低功耗以及更稳定的性能完成 Transformer 模型所需的计算任务。而最后这一点——稳定性——往往比人们想象得更加重要。对于交互式 AI 助手而言可预测的响应时间往往比极限性能更有价值。持续稳定地在约 1 秒内返回结果通常比平均耗时 0.8 秒但偶尔卡顿 5 秒的体验更好。在后续基准测试中我们将看到这一点NPU 不仅比 CPU 更快而且在响应稳定性方面领先一个数量级。此外NPU 的能耗也远低于 CPU。与让 12 个 CPU 核心持续满载运行相比使用 Hexagon NPU 执行推理意味着风扇保持安静设备温度更低电池续航时间更长。而对于一个始终在线的本地 AI Copilot 来说这正是其存在的意义。WinML CLI从模型源码到硬件优化产物关于 NPU人们常常忽略一个关键事实Hugging Face 上下载的模型并不能直接运行在 NPU 上。你无法直接把一个model.safetensors文件交给 Hexagon NPU然后期待它开始生成 Token。在“PyTorch 权重文件”与“真正运行在 NPU 上”之间还隔着一条完整的工程化流水线导出为 ONNX 格式、图优化、量化、编译为厂商专用上下文二进制文件。而这正是 Windows ML CLI 的价值所在。正如官方描述的那样它能够将来自 Hugging Face 或自定义训练流程的源模型通过可重复的工作流转换为面向特定硬件优化的部署产物。整个过程自动完成模型转换、图优化、模型编译并支持 AMD、Intel、NVIDIA 与 Qualcomm 等多种硬件平台。开发者既可以手动控制整个流程export → analyze → optimize → quantize → compile也可以直接使用winml build自动生成完整配置并完成构建。更重要的是同一套命令能够面向所有 Windows ML Execution Provider 工作。这意味着一次构建多种硬件运行。WinML CLI 本质上是一个通过 Python Wheel 安装的命令行工具可以轻松集成到 CI/CD 流程中。也正因为如此边缘 AI 部署终于从一次性的实验项目演进为可复现、可自动化、可规模化交付的工程实践。实战演练为 NPU 构建 Qwen3-0.6B这一部分是 winml-qwen3-chat 项目的核心内容。整个流程可以概括为五个步骤安装 → 检查 → 构建 → 性能测试 → 应用运行。0. 环境准备本项目在以下环境中完成验证Snapdragon X EliteARM64设备Windows 11 24H2NPU 支持必需Python 3.11uv 包管理工具用于示例应用.NET 10 SDK WinUI Workload1. 安装 WinML CLIWinML CLI 已发布至 PyPI可以通过 uv 创建独立环境并安装# Pin the exact Python the project needs uv python install 3.11 # Create and activate a 3.11 virtual environment uv venv --python 3.11 winml-env .\winml-env\Scripts\activate # Install the CLI from PyPI uv pip install winml-cli # Verify winml --version # - winml, version 0.1.0然后让 CLI 对你的机器进行自检——这是你的第一次“健全性检查”用来确认 NPU 是否真的可见winml sys在参考设备上这个命令会按优先级枚举所有三类计算单元NPU → GPU → CPU以及它们背后的执行提供程序QNNExecutionProvider、DmlExecutionProvider、CPUExecutionProvider。如果这里没有出现 NPU那么后续任何流程都无法使用它——因此winml sys 就是你进行问题诊断的起点。2. 构建前先检查模型 **在执行构建之前务必先执行 Inspect。**这样可以在几秒钟内发现模型架构是否受支持而不必等到导出流程运行了二十分钟后才发现构建失败。winml inspect -m Qwen/Qwen3-0.6B对于 Qwen3-0.6Binspect命令会展示即将构建模型的基本信息这是一个文本生成模型对应 WinML 中的WinMLModelForCausalLMComposite类模型架构为Qwen3ForCausalLM包含28 层隐藏层维度为1024词表大小为151,936使用ONNX Opset 17。其输入包括input_ids、attention_mask和position_ids输出则为logits。这里有一个值得尽早理解的重要细节Qwen3 是一个组合式模型。在导出过程中它不会被转换为单个 ONNX 计算图而是会导出为多个相互关联的 ONNX 组件。这一设计细节在后续量化阶段会变得尤为重要——事实上后面遇到的一些量化问题正是由这种组合式结构所带来的。不过换个角度看也正是这些问题帮助我们更深入地理解了模型部署链路中的关键环节。3. 为 NPU 构建模型下面这条命令完成整个核心构建流程winml build -m Qwen/Qwen3-0.6B -o output\qwen3-0.6b --ep qnn --device npu --compile -v该命令会自动执行Export、Optimize、Quantize、Compile全部针对 QNN Execution Provider 和 NPU 目标平台。底层运行分为四个阶段。以参考设备为例阶段时间输出Export133.2 秒export.onnx2.9GBOptimize157.6 秒optimized.onnx2.9GBQuantize227.6 秒quantized.onnx868MBCompile437.8 秒compiled_qnn.bin913MB总计1191.5 秒约20分钟model.onnx这四个阶段串联起来实际上浓缩了边缘 AI 部署的完整故事一个 2.9GB 的浮点精度模型首先被量化压缩至 868MB——转换为更适合 NPU 执行的整数精度表示随后再被编译为 Qualcomm HTP Context Binary即 Hexagon NPU 能够直接执行的计算图。最终生成的部署产物是output\qwen3-0.6b\model.onnx。它并不是一个普通的 ONNX 模型而是一个组合式入口图用于指向已经编译完成的 NPU Context。需要说明的是构建过程中产生的大约 9GB.onnx.data中间文件在构建完成后都可以安全删除以回收磁盘空间。不过项目文档也坦诚地指出了一个当前存在的限制由于文本生成任务尚未被纳入 WinML CLI 内置的校准任务列表因此在量化阶段工具会退回使用RandomDataset随机数据集来完成校准。对于以延迟测试为目标的性能基准来说这种做法是合理且无害的但如果目标是生产环境中的模型质量和生成效果这就会成为一个需要额外处理的问题。事实上这正是示例应用后续需要专门修复和优化的关键环节。4. 性能测试NPU vs CPU使用 WinML CLI 的 perf 命令测试模型性能# NPU (QNN) — runs the compiled context winml perf -m output\qwen3-0.6b\model.onnx --task text-generation --ep qnn --device npu --iterations 100 --warmup 10 # CPU — the compiled NPU graph cant run on CPU, so benchmark the # pre-compile quantized.onnx (QDQ) instead winml perf -m output\qwen3-0.6b\quantized.onnx --task text-generation --ep cpu --device cpu --iterations 50 --warmup 5测试结果序列长度 1024 的完整 Prefill Forward Pass设备EP精度平均延迟吞吐量标准差NPUQNNw16a16960.8 ms1.04 samples/s3.4 msCPUCPUw8a165793.3 ms0.17 samples/s828.3 ms这里有两个关键结论而第二个结论尤其值得关注在这一测试场景下NPU 的推理速度约为 CPU 的 6 倍。NPU 的性能稳定性约为 CPU 的 240 倍——其延迟标准差仅为 3.4 毫秒而 CPU 高达 828 毫秒。CPU 的推理延迟在不同运行之间可能波动接近整整 1 秒而 NPU 几乎每次都能在相同时间内完成推理。对于交互式聊天应用而言这种稳定性本身就是一种核心能力。这正是 Token 经济学在现实世界中的具体体现同一个模型运行在用户已经拥有的硬件设备上以接近零的 Token 边际成本提供接近云端服务级别的交互体验而且其响应时间甚至比 CPU 方案更加稳定、可预测。换句话说边缘 AI 的价值不仅在于更低的成本更在于能够以更稳定的方式交付高质量的用户体验。5. 从模型到应用仅仅拥有一个编译完成的.onnx模型并不意味着已经拥有了一个可交付的产品。为了弥合从“模型”到“应用”之间的差距winml-qwen3-chat项目提供了一个完整的桌面应用示例并直接基于前面构建的 NPU 模型运行app/WinMLChat/一个基于WinUI 3C# / .NET 10 / MVVM的聊天界面应用。它支持Token Streaming逐 Token 流式输出能够像 ChatGPT 一样实时展示生成内容从而将 NPU 低延迟且稳定的推理能力直接转化为流畅自然的“打字机式”交互体验。backend/一个基于FastAPI构建的后端服务。它对外提供与 OpenAI API 兼容的流式接口而底层模型加载与推理则由winml.modelkit.WinMLAutoModel驱动。整个项目中最值得关注的设计之一位于后端混合式 NPU / CPU 路由。对于较短的 Prompt请求会优先路由到经过量化的 NPU 模型以获得更高的推理速度和更低的功耗而对于较长的 Prompt则会自动切换到未量化的 CPU 推理路径以支持更长的上下文长度。从概念上看其路由逻辑类似于# Illustrative — the backend picks an execution path per request def choose_backend(prompt_tokens: int): if prompt_tokens NPU_PREFILL_LIMIT: return npu_model # quantized w16a16, QNN - fast, low-power return cpu_model # unquantized fallback - handles long context由于后端 API 采用了 OpenAI 兼容的流式接口协议因此 WinUI 前端以及任何兼容 OpenAI API 的客户端都能够直接接入而无需编写额外的适配层。换句话说NPU 的存在被隐藏在一个开发者熟悉的/chat/completions接口之下应用层无需关心底层究竟运行在 CPU、GPU 还是 NPU 上。面向生产环境的关键挑战为组合式 Decoder 修复量化流程还记得前面提到的 RandomDataset 校准警告 吗这其实正是“能够完成性能测试”和“能够交付生产应用”之间的一条真实分界线而项目也选择正面解决这一问题。WinML CLI 0.1.0 目前还无法开箱即用地完成 Qwen3 组合式 Decoder 在 QNN 平台上的量化。其默认的校准数据读取器遗漏了position_ids以及 28 层 Decoder 所需的 Past KVKey/Value Cache输入因此量化阶段使用的校准数据与模型实际运行时接收到的数据并不一致。示例项目通过backend/winml_npu_patch.py从根本上修复了这一问题具体包括提供真实的 KV Cache 校准数据即 Decoder 实际需要的position_ids以及每一层对应的 Past Key/Value Tensor改用Per-Channel W16A16 量化方案并将lm_head排除在量化范围之外。这正是“性能测试表现良好的模型”和“实际生成效果优秀的模型”之间的区别所在真正有效的量化需要基于具有代表性的真实输入进行校准而不是随机生成的数据同时对于像输出投影层lm_head这样对精度高度敏感的模块需要保留更高精度以确保生成 Token 的质量不会受到明显影响。仍有待完善之处如果在这里就开始庆祝成功那未免有些言过其实。毕竟这项工作仍处于早期阶段而这一点也体现在许多细节之中。Qwen3-0.6B——以及当前大多数小参数大语言模型——单独使用时仍然存在明显局限。0.6B 参数规模非常适合作为验证整条部署链路的技术样例但其推理能力相对有限。对于许多真实业务场景你可能仍然需要更大规模的本地模型、检索增强Retrieval能力或者边缘与云端协同的混合架构。某种程度上可以说硬件已经准备好了而小模型的能力仍在持续追赶。性能和优化方面同样还有提升空间。虽然当前的构建流程已经能够完整跑通但仍存在一些需要进一步打磨的地方文本生成任务的量化校准仍会退回使用 RandomDataset组合式 Decoder 仍需要额外编写补丁才能正确完成量化winml-cli 0.1.0 尚不支持算子级性能分析–op-tracing而本文展示的吞吐量数据也只是一个起点而非性能上限。后续仍有大量值得探索和调优的空间。不过这些问题并不是等待观望的理由恰恰相反它们正是参与进来的理由。整个工具链是开源的而且发展速度很快。推动其成熟最快的方式不是等待它变得完美而是在真实场景中使用它、测试它并反馈实际遇到的问题。如果你发现了 Bug、遇到了限制或者有新的想法欢迎前往 github.com/microsoft/winml-cli/issues 提交 Issue。来自真实构建和真实应用场景的反馈正是帮助这些工具不断完善的重要动力。总结边缘 AI 值得关注的原因并不在于“新奇”而在于经济规律和物理规律恰好指向了同一个方向。从Token 经济学的角度来看云端推理的每个 Token 都需要持续计费其边际成本永远无法降为零而边缘推理则通过一次性的硬件投入让后续 Token 的边际成本不断趋近于零。对于高频调用、交互密集以及隐私敏感的工作负载而言这并非微不足道的成本优化而是一种结构性的优势。NPU则是让这一模式真正可行的关键硬件。它专为 Transformer 模型的前向推理而设计在本文的测试中以远低于 CPU 的功耗实现了约 6 倍于 CPU 的推理性能以及约 240 倍于 CPU 的稳定性。WinML CLI则充当了连接模型与硬件之间的桥梁。它通过一条可重复、可自动化的流程——Inspect → Build → Perf——将 Hugging Face 模型转换为面向特定硬件优化的部署产物并支持 Windows ML 的所有 Execution Provider。而winml-qwen3-chat则将这一切串联起来一个真实运行在 NPU 上的 Qwen3-0.6B 部署案例、一份客观透明的性能基准测试、一个支持流式输出的 WinUI 聊天应用、一个兼容 OpenAI API 的混合路由后端以及——最具启发意义的——一个展示如何从“能够运行”走向“能够交付”的量化修复实践。对于开发者而言最值得关注的结论是**推理运行在哪里已经不再是一个部署细节而是一项架构决策。**当你的工作负载具有高调用频率、低延迟要求或严格隐私约束时答案越来越可能不是继续增加云服务预算而是充分利用用户设备中已经存在的 NPU。而今天通往这一目标的工具链已经准备就绪。从这里开始Sample Codekinfey/winml-qwen3-chatWinML CLImicrosoft/winml-cli