高通跃龙IQ-9100工业平台的开发经验分享(3): weights-packing-CLI与PythonAPI对比
设备: 高通跃龙IQ-9100 (IQ-9075, SA8775P同样适用, Hexagon v73, 双 CDSP)模型: Qwen2.5-7B-Instruct (w4a16 混合精度量化28 层 Transformer)SDK: QAIRT 2.42.0.251225日期: 2026-07-19概述QAIRT SDK 提供两条编译路径CLI 工具qnn-context-binary-generator和 Python APIqairt.compile()。对于 LLM 部署中的多图 context binary 编译这两条路径的行为存在关键差异——CLI 无法正确执行 4-bit 权重打包weights_packing导致产物体积膨胀 2 倍。本文记录这一差异的发现过程、根因分析、以及如何通过 Python API 实现与云编译等价的本地编译。一、问题本地编译产物是云编译的 2 倍在将 Qwen2.5-7Bw4a16 量化本地编译为 HTP context binary 时产物体积约 8.4 GB——而通过 Qualcomm AI Hub 云编译的同一模型仅 4.7 GB。逐层对比指标云编译 (6-split)本地编译 (11-split)每层 Transformer 大小112.75 MB224.2 MB总量4720.7 MB~8358.8 MB比率1.0×~2.0×224.2 ÷ 112.75 ≈ 1.99。对于 w4a16 量化模型精确 2 倍差异只有一个合理解释4-bit 权重没有被打包——每个 4-bit 值占了一整个 byte。二、QAIRT 工具链中的 4-bit 权重打包2.1qairt-converter的--pack_4_bit_weights参数QAIRT SDK 的模型转换器qairt-converter有一个参数--pack_4_bit_weights: Store 4-bit quantized weights in packed format in a single byte i.e. two 4-bit quantized tensors can be stored in one byte默认值为False。启用后DLC中间格式体积减半DLC 编译模式Part 2 大小缩减默认不打包676.4 MB—--pack_4_bit_weights343.0 MB-49.3%但 DLC 只是中间格式。最终部署到设备上的是 context binary由qnn-context-binary-generator从 DLC 编译而来。2.2qnn-context-binary-generator的编译模式差异这个 CLI 工具在单图模式和多图模式下的 weight packing 行为完全不同编译模式输入 DLCcontext binary 大小是否打包 4-bit单图未打包 676.4 MB337 MB✅ 内部自动打包单图已打包 343.0 MB编译失败(Error 1002)N/A多图prompttoken, weight sharing未打包 DLCs672.6 MB❌ 不打包LLM 部署必须使用多图模式prompt 图和 token 图共享权重而在这个模式下 CLI 工具不执行 4-bit 权重打包。更值得注意的是如果输入已经打包好的 DLC单图模式反而会报错nullptr for graphsInput。CLI 工具只能接受未打包的 DLC然后在单图模式下自行打包或在多图模式下跳过打包。2.3 跨平台验证为排除平台差异在 Windows 和 LinuxWSL2 Ubuntu 24.04上分别执行多图编译平台多图 Part 2 大小Windows (QnnHtp.dll)672.6 MBLinux (libQnnHtp.so)673 MB结果一致。多图模式不打包 4-bit 权重是qnn-context-binary-generator的固有行为与操作系统无关。三、CLI 配置文件的静默忽略问题3.1 HTP 后端扩展 schemaQNN HTP 后端定义了一套 JSON 格式的扩展配置htp_backend_ext_config.json包含graphs、context、devices等部分。其中graphs下的weights_packing键用于控制是否打包 4-bit 权重{graphs:[{graph_names:[prompt_ar128_cl4096_2_of_11,token_ar1_cl4096_2_of_11],weights_packing:true}],context:{weight_sharing_enabled:true}}3.2 CLI parser 的实际行为将上述配置通过--config_file传给qnn-context-binary-generator得到[ ERROR ] Unknown Key graphs/0/weights_packing passed in config [ ERROR ] Unknown Key graphs/0/O passed in config [ ERROR ] Unknown Key context/weight_sharing_enabled passed in configCLI 工具的 JSON parser没有实现完整的 HTP 后端扩展 schema。graphs、context、devices中的扩展配置键被识别为 “Unknown Key” 后静默忽略——工具继续以默认值运行不会中止。这意味着用户在配置文件中设置weights_packing: true→ 被忽略用户在配置文件中设置weight_sharing_enabled: true→ 被忽略用户在配置文件中设置optimization_type(O) → 被忽略工具输出 672.6 MB 的未打包 context binary看起来编译成功没有任何指示告诉用户这些配置项没有生效。“Unknown Key” 的 ERROR 级日志容易被淹没在其他输出中且工具正常退出exit code 0。四、Python API直接调用 QNN C APIQAIRT SDK 同时提供 Python APIqairt包其底层通过NativeExecutor直接调用 QNN C API不经过 CLI 的 JSON parser。4.1 关键代码importqairtfromqairt.api.compiler.configimportCompileConfigfromqairt.api.common.backends.htp.configimportHtpGraphConfig,HtpContextConfig# 转换 ONNX → DLC内存中的中间表示prompt_modelqairt.convert(prompt_onnx,encodingsprompt_enc,float_bitwidth16)token_modelqairt.convert(token_onnx,encodingstoken_enc,float_bitwidth16)# 编译 DLC → context binaryconfigCompileConfig(backendHTP,graph_custom_configs[HtpGraphConfig(nameprompt_name,optimization_type3,weights_packingTrue),HtpGraphConfig(nametoken_name,optimization_type3,weights_packingTrue),],context_custom_configs[HtpContextConfig(weight_sharing_enabledTrue)],)resultqairt.compile([prompt_model,token_model],configconfig)result.save(output_bin)4.2 配置参数说明参数作用CLI 是否支持weights_packingTrue将 2 个 4-bit 权重打包到 1 byte❌ 静默忽略optimization_type3最高优化级别❌ 静默忽略weight_sharing_enabledTrueprompt/token 图共享权重❌ 静默忽略float_bitwidth16浮点回退使用 fp16✅ 支持Python API 中这些参数通过HtpGraphConfig、HtpContextConfig等 Python 对象传递在底层被正确映射到 QNN C API 的对应接口。五、A/B 测试对比5.1 单 Part 对比Part 2 of 11编译方法Part 2 大小vs 云编译CLI默认不打包672.6 MB2×CLI weights_packing: trueJSON 配置672.6 MB2×被忽略Python API weights_packingTrue337.3 MB≈1×云编译参考值~340 MB1×5.2 全量编译对比Python API 编译全部 10 个 Transformer parts LUT 嵌入11-split 方案Part内容Python API 打包CLI 未打包缩减1 (LUT)嵌入层1039.5 MB1039.5 MB0%2–10Transformer 层每份 3 层337.3 MB × 9672.6 MB × 9-49.9%111 层 LM Head635.1 MB1266.8 MB-49.9%总计4710.4 MB~8358 MB-43.6%本地 Python API 编译 4710.4 MB vs 云编译 4720.7 MB差异仅 0.2%。六、与云编译参数的贡献度对比AI Hub 云编译管线中有两个本地不可用的参数# ai-hub-models 源码中硬编码other_compile_options --quantize_full_type w8a16 --quantize_io--quantize_full_type w8a16将未量化的嵌入层和 LM Head 从 fp16 量化为 w8a16--quantize_io量化模型的输入/输出张量这些参数的实际贡献因素贡献比例说明weights_packing~98-99%2 个 4-bit 值打包到 1 byte--quantize_full_type w8a16~1-2%仅影响嵌入层和 LM Head--quantize_io1%仅影响 I/O 张量体积差异的主导因素是weights_packing而这个功能通过 QAIRT Python API 在本地完全可用。云编译独有的量化参数对最终二进制大小的贡献不到 2%——4710 MB vs 4720 MB 的 10 MB 差异即来源于此。七、技术原因分析7.1 为什么 CLI 的多图模式不打包qnn-context-binary-generator的单图模式和多图模式在内部使用不同的编译路径单图模式直接调用 HTP 编译器编译器内部对 4-bit 权重执行打包多图模式--weight_sharing_enabled需要在多个图之间协调权重共享使用了不同的内部流程。这个流程中4-bit 权重打包步骤被跳过了这是 CLI 工具在多图编译路径中的实现缺陷不是 QNN HTP 编译器本身的限制——因为 Python API 调用的是同一个底层编译器且能在多图模式下正确执行打包。7.2 为什么 CLI 的 JSON parser 不识别扩展键CLI 工具的--config_fileJSON parser 实现了 HTP 后端配置 schema 的一个子集。以下类别的键被支持顶层设备配置soc_model、dsp_arch、cores内存配置mem_type性能配置perf_profile、rpc_control_latency以下类别的键不被支持报 “Unknown Key”graphs下的weights_packing、optimization_type(O)context下的weight_sharing_enabledPython API 的NativeExecutor则在 Windows 上通过QnnHtp.dllLinux 上通过libQnnHtp.so直接调用 QNN C API所有 HTP 后端扩展参数都被正确传递。八、本地编译完整流程以下是使用 Python API 编译 LLM context binary 的关键步骤8.1 环境要求项目要求Python3.10QAIRT SDK 的.pyd原生绑定要求QAIRT SDK2.42路径示例C:\Qualcomm\AIStack\QAIRT\2.42.0.251225环境变量QNN_SDK_ROOT指向 SDK 根目录Python path$QNN_SDK_ROOT/lib/python加入sys.path8.2 编译脚本核心逻辑importsys,os QAIRT_ROOTos.environ[QNN_SDK_ROOT]sys.path.insert(0,os.path.join(QAIRT_ROOT,lib,python))importqairtfromqairt.api.compiler.configimportCompileConfigfromqairt.api.common.backends.htp.configimport(HtpGraphConfig,HtpContextConfig,HtpDeviceConfig,HtpDeviceCoreConfig,PerfProfile,)NUM_SPLITS6forpart_idxinrange(1,NUM_SPLITS1):prompt_namefprompt_ar128_cl4096_{part_idx}_of_{NUM_SPLITS}token_nameftoken_ar1_cl4096_{part_idx}_of_{NUM_SPLITS}# 1. 转换 ONNX → DLCprompt_modelqairt.convert(prompt_onnx,encodingsprompt_enc,float_bitwidth16)token_modelqairt.convert(token_onnx,encodingstoken_enc,float_bitwidth16)# 2. 编译 → context binaryconfigCompileConfig(backendHTP,graph_custom_configs[HtpGraphConfig(nameprompt_name,optimization_type3,weights_packingTrue,vtcm_size_in_mb8),HtpGraphConfig(nametoken_name,optimization_type3,weights_packingTrue,vtcm_size_in_mb8),],context_custom_configs[HtpContextConfig(weight_sharing_enabledTrue)],device_custom_configs[HtpDeviceConfig(soc_model77,dsp_archv73,cores[HtpDeviceCoreConfig(perf_profilePerfProfile.BURST,rpc_control_latency100)],)],)resultqairt.compile([prompt_model,token_model],configconfig)result.save(fqwen2_5_7b_instruct_part_{part_idx}_of_{NUM_SPLITS}.bin)8.3 编译耗时6-split 全量编译在 Windows x86_64 上约16 分钟完成含 ONNX→DLC 转换 DLC→context binary 编译。九、影响评估9.1 消除云编译依赖在发现 Python API 的weights_packing之前获取紧凑 context binary 的唯一途径是 Qualcomm AI Hub 云编译。这意味着需要 AI Hub 账号和 API token需要上传数 GB 的 ONNX 模型到云端在网络条件差的环境下200 KB/s 上传速度意味着 17 小时需要等待云端排队和编译编译配置受限于云 API 提供的选项使用 Python API 后整个编译流程在本地 Windows 机器上 16 分钟完成不需要网络连接、不需要账号、不需要等待。9.2 对不同 QAIRT 版本的适用性weights_packing参数在 QAIRT 2.40 的 Python API 中可用。CLI 的 parser 限制在测试过的所有版本2.35、2.40、2.42中均存在。十、CLI 与 Python API 对比总结对比维度CLI (qnn-context-binary-generator)Python API (qairt.compile())4-bit weights_packing多图模式❌ 不执行✅ 正确执行weight_sharing_enabled❌ JSON parser 忽略✅ 正确传递optimization_type❌ JSON parser 忽略✅ 正确传递soc_model / dsp_arch✅ 支持✅ 支持底层调用方式内部实现直接调用 QNN C API (QnnHtp.dll/libQnnHtp.so)多图 context binary 大小~672 MB/part膨胀~337 MB/part紧凑总模型大小7B, 6-split~8.4 GB~4.7 GB与云编译大小差异2×0.2%编译时间类似~16 分钟结论QAIRT SDK 的 CLI 工具qnn-context-binary-generator在多图编译模式下不执行 4-bit 权重打包。这不是配置问题——即使在 JSON 配置文件中显式设置weights_packing: true也会被 parser 忽略。CLI 的 JSON parser 只实现了 HTP 后端扩展 schema 的一个子集。weights_packing、weight_sharing_enabled、optimization_type等关键配置项被报为 “Unknown Key” 后静默跳过工具以默认值继续执行并正常退出。QAIRT Python API 是多图 context binary 编译的正确路径。它通过NativeExecutor直接调用 QNN C API所有 HTP 后端扩展参数都被正确执行。产出的 context binary 与云编译在大小和推理质量上等价。本地编译可以完全替代 AI Hub 云编译。Python API weights_packingTruesoc_model77产出的 context binary 总量 4710 MB与云编译的 4720 MB 仅差 0.2%差异来自云端额外的--quantize_full_type w8a16和--quantize_io贡献不到 2%。对于 QAIRT SDK 的 LLM 部署流程建议统一使用 Python API 进行编译避免 CLI 工具的多图模式限制和 parser 不完整问题。

相关新闻

高通跃龙IQ-9100工业平台的开发经验分享(2): 7B模型推理乱码的根因追踪

高通跃龙IQ-9100工业平台的开发经验分享(2): 7B模型推理乱码的根因追踪

设备: 高通跃龙IQ-9100 EVK (SA8775P, Hexagon v73, 双 CDSP) 模型: Qwen2.5-7B-Instruct (w4a16 混合精度量化,28 层 Transformer) SDK: QAIRT 2.42 (本地编译) Genie 1.14.0 推理运行时 日期: 2026-07-23 一个缺失的编译参数导致了数周的调试——排除了 9 个错误…

2026/10/14 15:17:18 阅读更多 →
智能体面试准备(二十七):人机协作 HITL——审批流、接管、反馈闭环与可审计

智能体面试准备(二十七):人机协作 HITL——审批流、接管、反馈闭环与可审计

智能体面试准备(二十七):人机协作 HITL——审批流、接管、反馈闭环与可审计前面讲了多模态 Agent(B25)、成本工程(B26),把 Agent 的"感知"和"算账"都补齐了。但…

2026/10/7 10:24:21 阅读更多 →
AI 搜索可见性技术机制解析:10 个常见技术错误及其修复方案

AI 搜索可见性技术机制解析:10 个常见技术错误及其修复方案

文章目录 技术地基的底层逻辑:AI 爬虫如何发现与解析页面 AI 搜索引擎工作机制深度拆解 技术地基错误实证分析:三个致命配置问题 内容结构技术实现:信息块设计与平台适配算法 多平台分发策略的技术验证与数据对比 引用基线监控系统的代码实现 平台权重评估模型与数据验证 技…

2026/10/5 16:48:20 阅读更多 →

最新新闻

2026年最新--区块链运营岗面试题库(100题)

2026年最新--区块链运营岗面试题库(100题)

一、行业趋势与运营思维(1-10题) 1. 2026年加密行业营销的核心趋势有哪些?请结合“用户质量优先”的转变,说明运营策略应如何调整。 2026年加密营销的7大核心趋势涵盖绩效营销、内容创作、渠道多元化、活动体验、激励机制以及AI驱动的运营。最关键的转变是:Fintech和Web…

2026/10/14 15:17:11 阅读更多 →
C# GPS定位到地图显示:NMEA解析、坐标转换与GMap.NET实战

C# GPS定位到地图显示:NMEA解析、坐标转换与GMap.NET实战

简介:面向C#开发者和GIS初学者的GPS定位与地图综合示例源码。项目基于.NET框架,展示如何使用GeoCoordinateWatcher获取NMEA GPS数据,并通过Bing Maps控件实现地图加载、缩放、平移及城市名地理编码定位,涵盖地图事件处理、UI布局、…

2026/10/14 15:17:11 阅读更多 →
HTML表单与表格实战:学生注册表单与课程表制作全解析

HTML表单与表格实战:学生注册表单与课程表制作全解析

做了几年前端开发,接手过不少新人带教和作业评审。说句实在话,不管后来技术栈换成React还是Vue,凡是能把HTML里的表单和表格玩明白的,上手业务系统的效率往往都不会太差。这两块看起来基础,里面的门道却一点也不少——…

2026/10/14 15:17:11 阅读更多 →
工业AI检测项目为何死于“全产线覆盖”?

工业AI检测项目为何死于“全产线覆盖”?

1. 那句“全产线覆盖”,到底杀死了什么我做了七八年机器视觉和上位机开发,前前后后参与过二十多个工业AI项目,从服装检测、3C外观检、到食品包装异物识别都碰过。如果让我总结这些项目失败的最大共性,不是算法不行,不是…

2026/10/14 15:17:11 阅读更多 →
微信小程序商城定制怎么落地?选型要点全拆解

微信小程序商城定制怎么落地?选型要点全拆解

其实, 微信小程序商城定制这事儿, 说起来就是搭建一套能够实现商品售卖、会员管理以及营销推广的线上商业闭环, 不要被“定制”这两个字给吓到了, 要知道现在的SaaS平台已经把所有的基础功能都变成了现成的模块状态, 这些模块大概占据了整体功能总量的百分之八十的比例, 因此, …

2026/10/14 15:17:11 阅读更多 →
fast-check 4.7.0 深度解析:stringMatching 支持 Unicode 属性转义与可逆的 json 生成器

fast-check 4.7.0 深度解析:stringMatching 支持 Unicode 属性转义与可逆的 json 生成器

开发工具测试 【免费下载链接】fast-check Property based testing framework for JavaScript (like QuickCheck) written in TypeScript 项目地址: https://gitcode.com/gh_mirrors/fa/fast-check 点击查看 免费下载 fast-check 4.7.0 是一个围绕"让生成器更…

2026/10/14 15:16:08 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →