嵌入式大模型边缘部署(MTK方向)

📅 2026/7/13 14:19:45
嵌入式大模型边缘部署(MTK方向)
第一章大模型运行本质与边缘部署核心逻辑1.1 大模型运行的本质是什么?大语言模型LLM的运行本质是一个自回归Autoregressive的下一个词预测过程。它接收人类语言转化为数学矩阵并通过庞大的神经网络不断计算概率生成下一个最优结果。其运行过程严格分为两个核心阶段·Prefill预填充/Prompt阶段模型一次性接收用户的全部输入Prompt并行计算所有输入 Token 的注意力Attention特征生成首个输出词。这个阶段是典型的“计算密集型”对芯片的算力峰值要求极高。·Decode解码/生成阶段模型基于已有的输入和刚刚生成的词逐个生成后续的词。每次只输入一个 Token长度为 1这个阶段是典型的“访存密集型”对内存带宽Memory Bandwidth的考验极大。1.2 边缘侧部署我们需要对模型做什么与云端拥有数百 GB 显存的集群不同MTK 等移动端 SoC边缘设备面临着极其严苛的资源限制内存有限、带宽受限、且必须控制功耗与发热。为了让庞大的 LLM 在边缘设备流畅运行我们需要对它进行以下“改造”·模型量化 (Quantization)将模型原始的 FP16 浮点权重进行压缩。例如采用asym4W_sym16A权重非对称 4-bit激活值对称 16-bit策略。这能把模型体积缩小约 75%大幅降低内存占用突破带宽瓶颈。·图结构分离 (Split Prompt Generative)针对上文提到的 Prefill 和 Decode 特性我们将模型切分为两套执行图。处理长上下文的编译为长图如 128t单次处理 1 个 token 的编译为单图如 1t。·特定硬件后端映射将模型的算子通过专用编译器如 Neuron SDK翻译使其完全适配底层硬件加速模块如 MTK 的 MDLA 深度学习加速核心和 EDMA 内存搬运引擎。1.3 部署所需文件及其关系解构在端侧跑起一个大模型绝非一个文件就能搞定它是一个软硬协同的系统工程。核心文件及其相互关系如下端侧大模型推理架构与底层组件详解表核心模块层级包含的组件/文件运行硬件核心职能概述底层运行逻辑与系统级优化细节文本处理层(Tokenizer)vocab.txtmerges.txtadded_tokens.yamlCPU文本与数字化 ID 的双向翻译枢纽。预/后处理查表转换基础词(vocab)按 BPE 算法规则合并字符(merges)并赋予系统控制符最高保留优先级(added_tokens)。调度与环境层(Runtime HAL)libmtk_llm.somainchat_loop.shCPU(Host)异构计算的指挥中心与全生命周期管理。底层大脑负责初始化环境、分配物理内存/显存管理 Tensor 的数据搬移并将不同的计算任务精准派发给 CPU 或 NPU 处理。策略控制层(Configuration)config_*.yamlCPU定义生成多样性策略与系统边界。生成控制通过 Temperature 和 Top-P 超参数调节输出的随机性。底层通过比对输出的 ID 是否等于设定的 EOS来触发硬件中断并结束推理循环。权重复用层(Shared Weights)shared_weight.bin存储 -内存映射大幅降低端侧物理内存RAM占用防溢出。内存优化Prefill首字与 Decode逐字两张计算图复用同一套神经网络参数。通过内存映射避免权重双重加载防止端侧设备 OOM。特征映射层(Embedding)embedding_int16.binCPU将离散的 Token ID 映射为多维连续向量。异构拆分本质是内存密集型的“查表(Look-up)”操作。将其剥离交由 CPU 执行可避免挤占 NPU 宝贵的片上 SRAM (高速缓存)提升整体运行效率。硬件算力层(Execution Graph)qwen_128t.dlaqwen_1t.dlaNPU核心矩阵乘加(MAC)运算负责推理执行。离线编译图128t(Prefill图) 负责高并发吃透全量 Prompt追求吞吐量1t(Decode图) 负责自回归的单字生成此时主要受限于内存带宽瓶颈。第二章MTK 边缘部署实战演练以 Qwen2.5 为例2.1 模型量化准备与执行 (PTQ)在获得了原始模型后需对其进行后训练量化并固定模型形状npu对内存的格式很严格固定能够做到npu的内存消耗减少示例如下# 1. 提取校准数据集保证量化后精度不会大幅下降 bash 1_make_ptq_calibration_dataset.sh # 2. 执行量化过程 (此处应用 asym4W_sym16A 策略) bash 2_ptq.sh # 3. 固定模型形状 bash 3_shape_fixer.sh # 4. 可选在 PC 上运行 TFLite 格式以验证模型正确性 bash 4_optional_inference_tflite.sh2.2 适配目标芯片的硬件规格MTK不同平台的APU硬件能力不一。这里我们需要针对特定芯片及配合其指定的Neuron_SDK进行编译脚本改造我之前因为没有指定sdk出现过段错误打开编译脚本找到 BACKEND 等参数并进行修改修改这一步也特别重要如果size和平台设置错误后果也是很严重的# 修改前 (例如适配高端多核平台) BACKENDmdla5.5 L1_SIZE_KB7168 NUM_MDLA4 # 修改后 (适配当前平台芯片配置) BACKENDmdla5.3,edma3.6 # 指定具体的加速引擎版本 L1_SIZE_KB256 # 调整 L1 缓存大小 NUM_MDLA1 # 设置 MDLA 核心数2.3 模型编译与权重抽离硬件参数配置无误后使用 Neuron SDK 将网络编译为底层指令 DLA并将双流程复用的权重剥离出来以节约内存开销# 5. 编译预填充模型 (Prompt, 示例路径 1t2048c) bash compile_prompt_qwen2.5_0.5B_7B.sh ../post_training_quantize/tflite/ Qwen2.5-0.5B-Instruct_asym4W_..._1t2048c ~/work/MTK/neuron-8.0-release # 6. 编译生成模型 (Generative) bash compile_generative.sh ~/work/MTK/GAI-.../Qwen2.5-0.5B-Instruct_..._0.tflite ~/work/MTK/neuron-8.0-release # 7. 编译权重提取 (extract-shared.sh) # 将 128t (多Token) 与 1t (单Token) 模型中相同的权重提取至 shared_weight.bin bash extract-shared.sh ~/work/MTK/neuron-8.0-release shared_weight.bin path/ to/..._128t2048c_0.dla path/to/..._1t2048c_0.dla2.4 Tokenizer 提词器的准备C 的推理引擎无法直接读取 Python 生态的 tokenizer.json。必须经过转化。目前社区主要有两大流派其处理方式如下对于 HuggingFace 体系适用于 Qwen2.5: 需要借助提供的 Python 脚本将 JSON 提取为底层的 txt 与 yaml。python3 inference/scripts/prepare_huggingface_tokenizer.py ~/work/Qwen2.5-0.5B- Instruct/tokenizer.json # 生成附加特殊 Token 的 yaml python3 inference/scripts/prepare_added_tokens.py ~/work/Qwen2.5-0.5B-Instruct/ tokenizer.json对于 SentencePiece 体系适用于 Phi 等: 需对 .model 文件处理以剥除生成的虚拟前缀。python3 ./scripts/prepare_sentencepiece_tokenizer.py /path/to/tokenizer.model2.5 终极部署向设备进发完成所有编译后使用 Android 调试桥 (adb) 将产物统一推送到设备端。我们准备推送的文件分为两类核心模型库业务数据包含qwen_128t.dla qwen_1t.dla shared_weight.bin embedding_int16.bin config_qwen2.5_0.5b_instruct.yaml 及由上一步生成的 Tokenizer 系列文件vocab.txt、merges.txt 等。动态链接库与可执行程序驱动环境包含基础依赖 libc_shared.so libre2.so libyaml-cpp.so 分词引擎 libhf-tokenizer.so libsentencepiece.so libtokenizer.soMTK 推理框架主核心libmtk_llm.so libcommon.so libdrafter.so 以及执行程序入口 main至此只需在终端中执行 main即可成功在联发科平台设备的边缘侧唤醒该大语言模型并开始流畅对话参考资料Deploying Qwen2.5-0.5B onto Genio-720 with Android 15 - NeuroPilot / NeuroPilot - GenAI - MediaTek Genio Community