公开文章

端侧模型微调实战合集计划

以通用 Recipe JSON 生成模型为主线,讲清楚数据构建、QLoRA 微调、结构化验证、GGUF 量化和 Android 端侧部署

端侧模型微调实战合集计划

合集定位

合集名称:端侧模型微调实战

公众号定位

这不是一套“逐行讲代码”的微调教程,也不是把训练命令堆给读者的 runbook。

这个合集要讲的是一件更具体的事:

怎么把一个垂直生成能力训练进小模型,让它在端侧稳定输出可解析、可校验、可被 App 消费的结构化结果。

公众号负责讲清楚:

  • 为什么这个场景值得微调
  • 为什么不是直接 prompt、RAG 或云端 API
  • 数据怎么清洗,怎么变成训练样本
  • 小模型训完后,如何判断它真的可用
  • 从 LoRA 到 GGUF,再到 Android 本地推理,中间有哪些工程坑
  • 这种方法适合哪些端侧产品,不适合哪些场景

完整代码放在 GitHub,文章只保留关键片段、关键配置和关键判断。

一句话定位

用一个通用 Recipe JSON 生成模型,讲清楚“小模型如何学会一个垂直生成任务,并最终跑到端侧”。

主案例为什么继续用 Recipe

我们讨论过 PokéAPI、TMDB、Open Library 这些公开数据源,但它们都有一个共同问题:

它们更像事实查询,不像生成能力。

比如宝可梦图鉴,输入 pikachu 后输出图鉴 JSON,本质上很容易被读者质疑:

这件事为什么不用本地数据库查?

Recipe 的价值更强。因为用户输入不是一个固定 key,而是一段带约束的自然语言:

给我一份低脂、高蛋白、30 分钟内能完成的晚餐

模型要输出的也不是某条数据库原文,而是一份新的、结构完整的 recipe JSON:

title、description、ingredients、steps、nutrition、time、servings、tags ...

这更接近微调真正适合的任务:

  • 输入有变化空间
  • 输出不是死数据查询
  • 结果能被程序解析
  • 领域足够窄
  • 结构足够稳定
  • 端侧运行有意义

公开表达边界

Recipe 可以继续用,但文章里必须做隔离。

可以写:

  • 通用菜谱生成
  • 公开菜谱结构
  • 自建样例数据
  • 脱敏后的 recipe JSON
  • 本地 App 消费结构化结果
  • Android 端侧离线推理
  • 数据清洗、样本构建、QLoRA、GGUF、JSON 校验

不要写:

  • 公司名称
  • 内部项目路径
  • 内部接口
  • 真实业务来源
  • 具体设备类型
  • 设备控制参数
  • 任何可以联想到公司业务的字段

文章里的统一说法:

本文使用的是脱敏后的通用 Recipe JSON 示例,重点不在菜谱业务本身,而在“端侧小模型如何学习稳定的结构化生成能力”。

如果需要展示数据,全部使用通用字段和自造样例,不出现内部字段。

目标读者

  • Android、后端或全栈工程师,想切入端侧 AI
  • 已经会调用大模型 API,但不清楚微调到底解决什么问题的人
  • 对 LoRA、QLoRA、GGUF、llama.cpp 感兴趣,但不想一上来啃论文和源码的人
  • 正在做端侧 AI、本地推理、离线能力或结构化生成能力的开发者
  • 想把模型能力私有化、本地化、离线化的团队

GitHub 与公众号分工

文章只讲关键判断,完整代码放 GitHub。

内容 放公众号 放 GitHub
为什么选 Recipe 必须讲 README 简述
数据清洗 讲链路和坑 放完整脚本
训练样本设计 重点讲 放构建脚本和样本
QLoRA 参数 讲关键参数 放完整训练命令
推理验证 讲验证思路 放脚本和测试样例
GGUF / Android 讲链路和坑 放 runbook、JNI、Compose
失败案例和复盘 重点讲 可放 issue / notes

每篇文章固定保留一个小节:

## 完整代码在哪里|CODE

这篇对应仓库里的这些文件:

- `xxx.py`
- `yyy.sh`
- `README.md`

如果某篇文章先于代码发布,可以写成:

完整代码会放到 GitHub,本文先讲设计和关键片段。

合集基调与边界

这个合集的基调必须明确:

端侧微调不是把 ChatGPT 变小,而是让小模型在一个窄场景里稳定完成一个结构化生成任务。

Recipe 案例的重点不是“会不会做菜”,而是:

  • 用户输入是自然语言约束
  • 模型输出是稳定 JSON
  • App 可以解析、校验、展示或继续加工
  • 端侧推理可以降低延迟、减少网络依赖,并让体验更可控

应该少写:

长篇源码讲解 / 大段参数表 / 泛泛概念科普 / 训练命令堆叠 / 万能 AI 叙事

应该多写:

为什么选这个任务 -> 一开始哪里容易想错 -> 数据怎么变成样本 -> 训完怎么验证 -> 端侧落地还差什么

每篇代码控制原则:

  • 只贴 1-3 段关键代码
  • 单段代码尽量不超过 30 行
  • 复杂实现只给 GitHub 路径
  • 关键命令可以贴,但不把文章写成 runbook
  • 技术词首次出现必须用大白话解释

推荐目录结构

文章/2026-07/on-device-model-fine-tuning-practice/
├── plan.md
├── 01-why-fine-tune-on-device-model/
│   └── index.md
├── 02-recipe-data-cleaning/
│   └── index.md
├── 03-recipe-training-sample-design/
│   └── index.md
├── 04-qlora-training-small-model/
│   └── index.md
├── 05-inference-and-json-validation/
│   └── index.md
├── 06-merge-gguf-android/
│   └── index.md
├── 07-android-local-recipe-model/
│   └── index.md
└── 08-final-review/
    └── index.md

每篇如果需要配图,继续使用:

images/
├── covers/
└── illustrations/

图片 PNG 交付按当前规范走 2x:

  • 封面:900×383 设计,1800×766 导出
  • 正文插图:1200×900 设计,2400×1800 导出

公众号版文章规划

为什么端侧模型微调不是“把 ChatGPT 变小”

文章目标:先校准读者预期。微调不是让 0.5B 小模型变成通用专家,而是让它在一个窄场景里稳定输出指定结构。

核心问题

为什么不用云端大模型?为什么 prompt 不够?为什么 Recipe 这种生成任务适合讲微调?

建议结构

  • 从一个具体输入切入:低脂、高蛋白、30 分钟晚餐
  • 云端大模型能做,但端侧场景更看重离线、低延迟、成本和可控
  • prompt 能解决一部分,但很难长期保证字段完整、格式稳定、输出习惯一致
  • 微调真正解决的是“稳定输出格式”:字段有哪些、层级怎么组织、哪些值不能乱编
  • 哪些场景别急着微调:知识频繁变化、开放问答、数据少、规则能解决、RAG 更合适

关键代码/素材

  • SYSTEM_PROMPT
  • 一条输入约束对应的目标 Recipe JSON
  • 微调 / RAG / 规则 / 云端 API 选择矩阵

完整代码在哪里

  • README.md
  • recipe_constants.py
  • data/examples/recipe.target.json

可配图

  • 端侧微调不是压缩 ChatGPT,而是训练稳定输出格式
  • 用户约束 -> recipe JSON 输入输出示意图
  • 合集路线图

微调前最重要的不是训练,而是数据清洗

文章目标:把读者从“先跑训练脚本”的冲动里拉回来,讲清楚数据才是微调的地基。

核心问题

原始 recipe 数据为什么不能直接喂给模型?

建议结构

  • 原始数据通常会混着展示字段、元信息、无关状态、空值和历史字段
  • 为什么要先保留 raw,再做 normalized
  • 哪些字段适合进入目标 JSON:标题、简介、食材、步骤、时间、份量、营养、标签
  • 哪些字段不要进入训练:内部 ID、来源 URL、状态字段、媒体字段、业务字段
  • 为什么字段名、单位、数组顺序都要稳定
  • 为什么公开文章只能使用脱敏样例

关键代码/素材

  • normalize_recipe
  • should_keep_recipe
  • normalize_detail_summary.json

完整代码在哪里

  • normalize_recipe_details.py
  • data/raw/
  • data/normalized_detail/
  • data/examples/

可配图

  • raw detail -> normalized detail 字段清洗图
  • 保留字段 / 删除字段对照图

训练样本怎么设计,决定了模型到底学什么

文章目标:讲清楚最关键的设计:训练输入不要像数据库导出,要像真实用户会说的话。

核心问题

模型到底是在“复述菜谱”,还是在学习“根据用户约束生成可用 Recipe JSON”?

建议结构

  • 错误做法:把完整 metadata 塞进 prompt,让模型复述
  • 真实使用时,用户只会给菜名、饮食目标、时间限制、食材限制
  • 多 prompt 变体如何提升鲁棒性
  • target JSON 为什么要剔除内部字段和不稳定字段
  • 顶层字段为什么要固定
  • system prompt 必须训练和推理共用

关键代码/素材

  • build_prompt_variants
  • build_target
  • SYSTEM_PROMPT

完整代码在哪里

  • build_generation_dataset.py
  • recipe_constants.py
  • data/finetune_generation/train.jsonl
  • data/finetune_generation/val.jsonl

可配图

  • 旧训练范式 vs 新训练范式
  • 一条 recipe 扩成多条训练样本

QLoRA 实战:小模型训练不是越大越好

文章目标:讲训练本身,但不写成训练脚本说明书。重点解释为什么 0.5B / 1.5B 小模型是端侧案例的合理起点。

核心问题

为什么不是全量微调?为什么不是直接上 7B?

建议结构

  • 端侧目标决定了模型不能太大
  • QLoRA 用大白话解释:基座冻结,只训练一层小补丁
  • 4-bit、LoRA adapter、target modules 各自解决什么问题
  • batch、梯度累积、学习率、epoch、max_seq_length 怎么理解
  • 训练完成后产物是什么:不是完整模型,而是 adapter
  • 先把任务训稳,再谈更大模型

关键代码/素材

  • LoraConfig
  • BitsAndBytesConfig
  • SFTConfig 关键配置
  • train_generation_lora.sh

完整代码在哪里

  • train_generation_lora.py
  • train_generation_lora.sh

可配图

  • QLoRA 训练结构图
  • adapter / base model / merged model 关系图

训完怎么验证:别只看 loss,要看 JSON 能不能用

文章目标:把“训练成功”从 loss 拉回业务可用性。

核心问题

模型输出看起来像菜谱,但程序真的能解析和展示吗?

建议结构

  • eval loss 能说明什么,不能说明什么
  • 结构化输出必须看 JSON 可解析率
  • 必看指标:字段完整率、类型合法率、单位合法率、步骤缺失率、截断率
  • 用约束输入做验证:低脂、素食、20 分钟、少食材
  • 不能只测训练集中见过的 prompt,要换问法测
  • adapter 推理验证时 chat template 要和训练一致

关键代码/素材

  • infer_generation_lora.py
  • JSON parse / schema validate 伪代码
  • validate_recipe_output

完整代码在哪里

  • infer_generation_lora.py
  • validate_recipe_json.py
  • data/finetune_generation/dataset_summary.json

可配图

  • prompt -> raw output -> JSON parse -> schema validate 链路
  • 训练指标 vs 产品指标对比图

从 LoRA 到 GGUF:模型怎么变成端侧能跑的文件

文章目标:讲训练产物怎么变成 Android 端侧可部署的模型文件。

核心问题

为什么 adapter 不能直接丢到 Android 里跑?

建议结构

  • adapter 只是增量权重,不是完整模型
  • 为什么要 merge_and_unload
  • 合并后为什么还要转 GGUF
  • Q4_K_M 量化解决什么问题
  • 模型文件命名、版本、hash、发布目录怎么管理
  • 转完后先做 sanity check,不要直接进 App

关键代码/素材

  • merge_lora_adapter.py
  • convert_to_gguf.sh
  • 产物目录结构

完整代码在哪里

  • merge_lora_adapter.py
  • convert_to_gguf.sh
  • docs/model_release.md

可配图

  • adapter -> merged HF -> f16 GGUF -> Q4_K_M GGUF
  • 模型版本发布流程

Android 本地跑 Recipe 生成模型

文章目标:把合集从训练拉回 Android 工程。

核心问题

模型文件能跑起来,离产品可用还差什么?

建议结构

  • GGUF 文件放哪里:assets、下载、私有目录、版本更新
  • llama.cpp / JNI 调用路径
  • Android 侧 prompt template 必须和训练保持一致
  • 流式输出怎么接 UI
  • 模型初始化耗时、内存峰值、线程数怎么采样
  • 失败时如何回退模板、云端或提示用户重试

关键代码/素材

  • Android Termux 跑通记录
  • Kotlin / Compose / JNI 接入材料
  • 性能采样日志格式

完整代码在哪里

  • ANDROID_TERMUX_RUNBOOK.md
  • ANDROID_KOTLIN_COMPOSE_JNI.md
  • Android 示例工程路径后续补充

可配图

  • Android 本地推理架构图
  • 模型下载、校验、加载、推理、回退流程图

复盘:哪些场景值得微调,哪些别碰

文章目标:收束合集,给出工程判断框架。

核心问题

看完 Recipe 项目后,读者怎么判断自己的业务要不要微调?

建议结构

  • 这个项目证明了什么:小模型可以学会窄领域结构化生成
  • 它没有证明什么:不能替代通用大模型
  • 适合微调的任务:垂直、稳定、可评测、强格式、可离线
  • 不适合微调的任务:知识频繁变化、开放问答、数据太少、规则就能解决
  • 微调 vs RAG vs 规则 vs 云端 API
  • Android 工程师可以怎么把这条能力迁移到自己的端侧产品里

完整代码在哪里

  • GitHub 仓库首页
  • docs/fine_tuning_guide.md
  • 各篇文章对应脚本

可配图

  • 微调 / RAG / 规则 / 云端 API 决策树
  • 端侧模型工程闭环总结图

发布节奏建议

建议先按 8 篇公众号版推进:

  • 端侧微调解决什么问题
  • Recipe 数据清洗
  • Recipe JSON 训练样本设计
  • QLoRA 微调小模型
  • 推理验证与 JSON 校验
  • 合并、GGUF、量化
  • Android 本地部署
  • 微调场景复盘

如果后续读者反馈技术细节需求很强,再拆出番外篇:

  • TRL 版本兼容踩坑
  • assistant-only loss 真的有必要吗
  • 多语言字段怎么处理
  • 端侧 JSON 修复器怎么写
  • Android llama.cpp JNI 性能优化
  • Recipe 生成任务什么时候应该改用 RAG

单篇文章推荐结构

每篇文章都可以沿用这个结构:

## 这篇解决什么问题

## 我一开始怎么想错了

## 最后采用的方案

## 关键代码片段

## 完整代码在哪里|CODE

## 这一步踩过的坑

## 下一篇做什么

正式写作时可以根据内容灵活调整,但必须保留“完整代码在哪里|CODE”。

写作注意事项

  • 每篇只讲一个主问题,不要把整套流水线塞进一篇
  • 标题不要手写「一、二、三」或「①、②、③」,默认主题会自动承担章节感
  • 代码要有,但不要堆满;优先贴关键函数、关键配置、关键命令
  • 完整代码统一引导到 GitHub,不在公众号里逐行解释
  • 每篇都要有“为什么这么设计”,不要只写“执行这个命令”
  • 涉及 API key、内部接口、真实业务数据时,要脱敏或改成占位符
  • 不写公司名称、内部项目路径、具体设备类型、设备控制参数
  • 微调效果不要吹满,要明确边界:小模型、垂直任务、结构化输出、端侧约束
  • Recipe 案例只呈现通用字段和自造样例,正文配图用流程图、JSON 卡片和端侧架构图
  • 每篇结尾都给下一篇留钩子,形成合集连续感

第一篇建议

第一篇建议先写:

我用 Recipe 训练了一个端侧小模型:微调真正适合的场景

它适合作为合集开篇,因为它能先把读者的预期校准好:

  • 微调不是让 0.5B 小模型变成通用专家
  • 端侧模型也不是云端大模型的廉价替代
  • 真正适合微调的是垂直、稳定、可评测、强结构任务
  • Recipe 生成比事实查询更能体现微调价值

第一篇不需要写太多训练代码,重点讲:

问题 -> 为什么 Recipe 比事实库更适合 -> 微调到底学什么 -> 公开表达边界 -> 这个合集会怎么做

配图建议:

  • 封面:小模型、本地 Recipe JSON、Android 端侧设备的技术感组合
  • 正文图 1:微调 / RAG / 规则 / 云端 API 的选择矩阵
  • 正文图 2:用户约束 -> recipe JSON 输入输出示意图
  • 正文图 3:合集路线图

关注公众号

不错过后续文章和配套资源

扫码关注「唐人Console」,获取文章更新、配套资源和领取入口。 需要解锁时,文章页会生成专属口令。

唐人Console二维码扫码关注