Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 37 additions & 2 deletions docs/transformers/llm.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,39 @@ python llmexport.py \
cmake .. -DMNN_BUILD_CONVERTER=ON && make -j16
```
编译完成后 `build/` 目录下会生成 `MNNConvert` 可执行文件,`llmexport.py` 默认会在 `../../../build/` 下查找该工具;也可以通过 `--mnnconvert` 选项显式指定 MNNConvert 路径。若未提供本地 MNNConvert,脚本会回退到 pymnn(需先安装 `pip install MNN`)。此方案目前支持导出4bit和8bit模型。
- 导出 segment 形式的 MNN LLM,使用 `--export mnn --segment`。该模式从 safetensors 权重和 workflow JSON 直接生成多个 MNN 子图,跳过 ONNX 中间文件,适合在 Metal 等后端上复用 decoder、logit、embedding 等 segment 模型。默认会在 `resource/*.json` 中查找匹配的 workflow,也可以通过 `--workflow /path/to/workflow.json` 显式指定。

```bash
cd transformers/llm/export
python3 llmexport.py \
--path /path/to/Qwen3-0.6B \
--export mnn \
--segment \
--dst_path ./model
```

segment 导出目录包含:

```text
model/
├── config.json # llm_demo 入口配置,包含 "mnn_llm_version": "segment"
├── llm_config.json # 模型结构和模板配置
├── tokenizer.mtok
├── embed.mnn
├── decoder.mnn
├── decoder.mnn.weight
├── logit.mnn
├── logit.mnn.weight
└── logit_topkv_1.mnn
```

运行 segment 模型时需要使用生成的 `config.json`:

```bash
./llm_demo transformers/llm/export/model/config.json /path/to/prompt.txt
```

C++ 运行时需启用 `MNN_BUILD_LLM=ON`,并打开 `MNN_LLM_SUPPORT_SEGMENT`(默认开启)。segment 路径当前仅支持 `--export mnn`,不支持 `--export onnx`。
- 如果直接转为mnn模型遇到问题,或者需要其他bits数的量化(如5bit/6bit),可以先将模型先转为onnx模型,使用`--export onnx`,然后使用./MNNConvert工具将onnx模型转为mnn模型:

```
Expand All @@ -197,7 +230,7 @@ usage: llmexport.py [-h] --path PATH [--type TYPE] [--tokenizer_path TOKENIZER_P
[--gptq_path GPTQ_PATH] [--dst_path DST_PATH] [--verbose] [--test TEST] [--export EXPORT]
[--onnx_slim] [--quant_bit QUANT_BIT] [--quant_block QUANT_BLOCK]
[--lm_quant_bit LM_QUANT_BIT] [--mnnconvert MNNCONVERT] [--ppl] [--awq] [--omni] [--sym] [--seperate_embed]
[--lora_split]
[--lora_split] [--segment] [--workflow WORKFLOW]

llm_exporter

Expand All @@ -219,6 +252,8 @@ optional arguments:
--verbose Whether or not to print verbose.
--test TEST test model inference with query `TEST`.
--export EXPORT export model to an onnx/mnn model.
--segment export segment MNN LLM from safetensors workflow directly, without ONNX export.
--workflow WORKFLOW workflow json for --segment safetensors conversion. If absent, search resource/*.json.
--onnx_slim Whether or not to use onnx-slim.
--quant_bit QUANT_BIT
mnn quant bit, 4 or 8, default is 4.
Expand Down Expand Up @@ -1158,4 +1193,4 @@ adb push model /data/local/tmp/MNN/model
```
cd ${MNN_ROOT}
project/android/testCommon.sh ./llm_demo model/config_mlda.json
```
```
34 changes: 34 additions & 0 deletions resource/qwen3_hf_0.6b.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"models": [
{
"name": "hf_decoder",
"blocks": [
{
"type": "QwenTransformer",
"hiddenSize": 1024,
"headDim": 128,
"numHead": 16,
"kvNumHead": 8,
"number": 28,
"max_position_embeddings": 40960
}
]
},
{
"name": "logit",
"blocks": [
{
"type": "InnerProduct",
"prefix": "lm_head"
},
{
"type": "TieEmbedding"
},
{
"type": "TopKV",
"K": [1, 5]
}
]
}
]
}
14 changes: 11 additions & 3 deletions skills/support-new-llm/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
---
name: support-new-llm
description: 为 MNN 框架添加新的 LLM 模型支持。支持从 HuggingFace/ModelScope 下载模型,分析架构,添加映射,Hook 对齐测试,导出 MNN 模型。采用 TDD 模式,分 6 步执行,每步有独立测试标准。
description: 为 MNN 框架添加新的 LLM 模型支持。支持从 HuggingFace/ModelScope 下载模型,分析架构,添加映射,Hook 对齐测试,导出 MNN 模型;当用户明确要求 safetensors/segment/workflow/MNNConvert -f ST 时,走 safetensors segment 补充分支。采用 TDD 模式,分 6 步执行,每步有独立测试标准。
---

# MNN LLM 新模型支持 SKILL

> **触发条件**:当用户请求支持/添加/适配一个新的 LLM 模型时触发。常见表述包括:"支持xxx模型"、"添加xxx模型支持"、"适配xxx"、"导出xxx模型"等。
> **触发条件**:当用户请求支持/添加/适配一个新的 LLM 模型时触发。常见表述包括:"支持xxx模型"、"添加xxx模型支持"、"适配xxx"、"导出xxx模型"等。若用户明确提到 `safetensors`、`--segment`、`workflow.json`、`MNNConvert -f ST` 或“绕过 ONNX 直接转换”,先读 `safetensors-segment.md`。

## 概述

Expand All @@ -20,6 +20,8 @@ MNN 的模型导出本质上是**对照 HuggingFace transformers 库中原始模
3. 用 Python `--test` 验证映射正确性
4. 导出 MNN 模型并用 C++ 引擎验证

默认导出链路是 `llmexport.py --export mnn`。如果目标是 safetensors segment 格式,则使用 `llmexport.py --export mnn --segment`,按 `safetensors-segment.md` 先校验 workflow、safetensors key 和 builder 约定。

### 注意事项

> **🚨 严禁将输出错误归因于"量化精度不够"**:4bit 量化的 0.5B 小模型都能正确输出。如果 C++ 输出完全不对(如图片识别不出、输出乱码),**一定是实现细节没有与 HF 对齐**,必须逐步 dump 数据对比定位,不要靠猜。
Expand All @@ -44,6 +46,9 @@ MNN 的模型导出本质上是**对照 HuggingFace transformers 库中原始模
| `transformers/llm/export/utils/audio.py` | Audio Encoder 实现 | 音频模型 |
| `transformers/llm/export/utils/custom_op.py` | 自定义算子导出 | 新算子时 |
| `transformers/llm/export/llmexport.py` | 导出主流程入口 | 偶尔 |
| `transformers/llm/export/segment.py` | safetensors segment 导出入口 | segment 分支 |
| `resource/*.json` | safetensors workflow 模板 | segment 分支 |
| `tools/converter/source/safetensors/*.cpp` | safetensors converter / builder 实现 | segment 分支 |

---

Expand Down Expand Up @@ -98,6 +103,7 @@ MNN 的模型导出本质上是**对照 HuggingFace transformers 库中原始模
| Tier 4 (音频模型) | 1 → 2 → 3 → 5 → 4 | 需要 audio.py |
| Tier 5 (视觉模型) | 1 → 2 → 3 → 5 → 4 | 需要 vision.py |
| Tier 6 (全新架构) | 1 → 2 → 6 → 3 → 4 | 需要新算子(如叠加 Tier 4/5 则加入 step5) |
| Safetensors segment | 1 → S1/S2/S3 → S4/S5 | 明确要求 `--segment` / workflow / `MNNConvert -f ST` 时,参见 `safetensors-segment.md` |

---

Expand Down Expand Up @@ -185,8 +191,10 @@ modeling_*.py 中是否有全新的 Attention 类型(非标准 SDPA)?

**在开始之前,建议先浏览 `common-pitfalls.md`**,了解已知的常见问题和解决方案(RoPE 变体、dtype 级联、Jinja 限制、stop token、残差模式、MoE 支持要点、FakeLinear axis 陷阱、**do_map 静默失败与 rope_theta 间接存储**、非标准模型加载等)。

**Safetensors segment 分支的常见问题**:workflow 超参与权重 shape 不匹配、builder 预期 key 前缀不存在、自动 workflow 匹配选错、segment runtime 没启用。详见 `safetensors-segment.md`。

---

## 开始执行

**现在请打开 `skills/support-new-llm/step1-analyze.md`,开始步骤 1。**
**现在请打开 `skills/support-new-llm/step1-analyze.md`,开始步骤 1。若用户明确要求 safetensors segment 导出,同时打开 `skills/support-new-llm/safetensors-segment.md`。**
Loading
Loading