语言模型微调实战(01):为什么要微调与路线图
通用 Instruct 模型已经很会对话,但接到垂直任务时常常「不够稳」。这一篇先不写命令,而是把「为什么要微调、目标是什么、整条路线怎么走」讲清楚。 基座模型哪里不够?通用 Instruct 模型接到垂直任务时,常见短板是: 行为约束不够稳:角色、口吻、拒答边界容易漂移。 结构化输出不可靠:下游系统需要固定 schema(例如 JSON),模型却经常用自然语言「解释一遍」。 微调的目标,通常就是两件事同时推进: 让模型更贴合任务人设与领域表达; 让模型在「需要结构化输出」时,稳定产出可解析结果。 推荐路线图1234567891011定义任务与输出 schema ↓构造监督数据(Alpaca JSONL) ↓互斥划分 train / val ↓LLaMA-Factory:SFT + LoRA ↓合并适配器 → 完整模型 ↓离线评估 +(可选)推理侧校验 为什么起步用 LoRA,而不是全量微调?因为对中小规模监督数据,LoRA 通常已经够用:显存更省、迭代更快、产物更小。全量微调可以作为后续对比实验...
语言模型微调实战(00):系列导读
用 LLaMA-Factory 对 Qwen2.5-3B-Instruct 做一次 LoRA 监督微调(SFT),把「跑通流程 → 看懂评估 → 提升泛化」完整走一遍。这不是官方 README 的摘抄,而是一次可复现实验的方法论复盘。 这个系列讲什么 为什么要微调,而不是直接用基座模型? SFT 和 LoRA 分别指什么? 环境怎么搭、配置怎么写? 训练日志怎么读、轮数怎么选? 评估指标怎么选、失败案例怎么归因? 如何用「数据增强 + 推理侧约束」提升结构化输出的可靠性? 文中示例均为虚构示意,不引用真实业务语料,也不公开任何训练/验证样本。 技术栈(脱敏后) 项目 选型 基座模型 Qwen2.5-3B-Instruct 微调框架 LLaMA-Factory 训练阶段 SFT(监督微调) 训练方法 LoRA 运行环境 Ubuntu + NVIDIA GPU + Docker 数据格式 Alpaca 风格 JSONL(示意) 阅读路线 序号 主题 00 本篇:系列导读 01 为什么要微调,以及整体路线图 02 SF...
多模态微调实战(10):命令速查表
系列收尾,把全流程命令收进一页,方便复制粘贴。把项目根目录记为 ~/projects/vlm-ocr-sft(请替换),以下命令默认已有 script/docker_run.sh 或等价封装。 这是「多模态微调实战」的第 10 篇,也是收官篇。前九篇讲原理与取舍,这一篇只留命令。 环境123nvidia-smibash script/docker_run.sh swift --versionbash script/docker_run.sh python -c "import torch; print(torch.cuda.is_available())" 数据1234567891011121314# 演示子集python3 script/convert_lmdb_to_jsonl.py \ --project-root /workspace \ --train-samples 2000 \ --val-samples 200# 全量(参数按你的脚本约定)python3 script/convert_lmdb_to_jsonl.py \ --...
多模态微调实战(09):踩坑与经验清单
把这次实践里真正耗时间的坑集中写在这里,方便检索。环境依赖、GPU 被静默占用、评测口径、全量运维、合并导出、量化——每一类都有几个反复出现的问题。 这是「多模态微调实战」的第 09 篇。前八篇讲「怎么做对」,这一篇讲「哪里容易做错」。 一、环境与依赖1.1 datasets 版本冲突现象:训练启动时报奇怪的 ImportError / JSON 相关错误。处理:把 datasets 固定到与当前 ms-swift 匹配的范围(实践中用过 >=4.4,<4.8.5),并写进镜像或启动脚本。 1.2 没有 flash-attn现象:--attn_impl flash_attn 直接失败。处理:改用 --attn_impl sdpa,先求稳。 1.3 DeepSpeed / mpi4py现象:单卡强行上 deepspeed 反而更麻烦。处理:16GB 单卡 LoRA + 梯度检查点通常够用;深造优化留给真的多卡或更大模型。 二、GPU 被静默占用现象:训练刚启动 OOM,但「我没在训啊」。排查: 12nvidia-smidocker ps 常...
YOLO 目标检测实战(07):FastAPI 推理服务部署
目标:把检测能力封成 HTTP 服务——上传图片,返回 JSON 框或标注图,优先加载 TensorRT engine。至此,从环境到对外服务的一条链路就闭合了。 这是「YOLO 目标检测实战」的第 07 篇(收尾)。完整目录见 00 · 系列导读。 一、服务职责api/main.py 是一层薄封装: 启动时解析模型路径并 warmup(空图跑一次 predict,避免首请求卡住); GET /health:返回状态、模型路径、后端后缀(engine / pt / onnx); POST /predict:multipart 上传图片;可选 conf、imgsz、return_image。 模型加载优先级 环境变量 YOLO_MODEL weights/best.engine runs/train/coco128/weights/best.pt weights/yolo_s.pt compose 里 api 服务默认设置: 1YOLO_MODEL=/workspace/weights/best.engine 宿主机端口映射为 18080 → 容...
多模态微调实战(08):GGUF 与 INT4 的部署侧落地
训练与合并解决的是「模型变强」。真正进业务,还经常要面对 llama.cpp 生态、更小体积与更高吞吐——愿意用一点精度换部署成本。于是进入:导出 GGUF → 量化 → 用同一评测集验收。 这是「多模态微调实战」的第 08 篇。这一步决定模型能否装进内存紧张的本地 / 边缘环境。 说明:多模态 VLM 的 GGUF 导出链路比纯文本更挑版本与转换脚本。本文按「你已能把合并后的模型转到 GGUF」来写验收与取舍;具体转换命令请对齐你使用的 llama.cpp / 转换工具版本。 一、为什么还要 GGUF 诉求 GGUF 的价值 本地推理 llama.cpp / 各类绑定成熟 量化灵活 Q8 / Q4 / IQ 等一堆档位 分发 单文件或少量文件,运维简单 边缘 INT4 可明显降带宽与内存 代价是:多模态支持要确认工具链版本;量化必然有精度损失;评测必须用同一套验证集与同一套指标脚本。 二、推荐对比矩阵至少做三档(能做几档做几档): 版本 目的 HF 合并模型(bf16/...
Ubuntu 升级内核后 Kernel Panic:VFS: Unable to mount root fs on unknown-block(0,0) 修复实录
一台 Ubuntu 24.04 机器升级 HWE 内核后重启失败,屏幕停在 VFS: Unable to mount root fs on unknown-block(0,0)。这类故障最容易被误判为「根分区坏了」,但真正的根因往往是 initramfs 没有生成。本文完整记录从临时恢复、逐层排查到最终修复的全过程,并梳理出一套通用排障思路。 故障现象一台 Ubuntu 24.04 机器升级 HWE 内核后重启失败,屏幕显示: 1Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0) GRUB 中选择旧的 6.17.0-35-generic 可以正常启动,但默认选择的7.0.0-28-generic 无法进入系统。 unknown-block(0,0) 中的 (0,0) 是一个重要线索:内核启动后没有得到可用于挂载根文件系统的块设备。这通常意味着 initramfs 缺失、损坏,或者 initramfs 中缺少存储控制器、LVM、RAID、加密卷等启动所需模块。它不一定代表...
YOLO 目标检测实战(06):TensorRT 导出与三后端基准
目标:导出 FP16 TensorRT engine,并在同一张图上对比 PyTorch / ONNX / TensorRT 三个后端的平均延迟,看看引擎到底快在哪。 这是「YOLO 目标检测实战」的第 06 篇。完整目录见 00 · 系列导读。 一、导出 TensorRT容器内需已安装 tensorrt(镜像已 pin tensorrt-cu12;脚本在缺失时会尝试安装固定版本)。 1bash scripts/06_export_tensorrt.sh 关键参数: 1234567yolo export \ model=/workspace/runs/train/coco128/weights/best.pt \ format=engine \ imgsz=640 \ device=0 \ quantize=16 \ workspace=4 说明: quantize=16 → FP16 engine(新卡上常用默认,不必再传已弃用的 half 写法); workspace=4:构建时的工作空间(GB 量级),可按显存调整; 生成的 b...
多模态微调实战(07):合并 LoRA 得到完整模型
LoRA checkpoint 很小,但推理时需要「基座 + adapter」。若要交给只接受普通 HF 目录的下游,或继续转 GGUF,通常先 merge。这一篇讲合并在做什么、怎么做、合完怎么验。 这是「多模态微调实战」的第 07 篇。合并是从「训练产物」走向「可部署模型」的关键一步。 一、合并在做什么把 LoRA 低秩更新写回基座线性层,导出一份独立完整权重: 1基座 Qwen3-VL-4B + adapter(checkpoint-XXXXX) → merged model directory 合并后: 不再依赖 --adapters; 目录结构接近普通 Transformers 模型; 体积接近基座(数 GB~十余 GB),而不是 LoRA 的几百 MB。 二、命令ms-swift: 12345swift export \ --model /workspace/model/Qwen3-VL-4B-Instruct \ --adapters /workspace/output/ocr_plate_lora_full/.../checkpoint-...
YOLO 目标检测实战(05):导出 ONNX 与结果对齐
目标:把 best.pt 导出为 ONNX,并用同一张图对比 PyTorch 与 ONNX 的检测框,确认导出没有「悄悄跑偏」。导出成功 ≠ 导出正确,这一篇的重点就是那道对齐检查。 这是「YOLO 目标检测实战」的第 05 篇。完整目录见 00 · 系列导读。 一、为什么先做 ONNX ONNX 是跨框架部署常见的中间格式,也便于后续再转其他 runtime; 相对 TensorRT engine,ONNX 更易在不同机器间拷贝试跑(仍建议同环境复现); 对齐脚本能在上 TensorRT 之前,先把导出问题拦下来。 二、导出容器内: 1bash scripts/04_export_onnx.sh 核心命令: 12345yolo export \ model=/workspace/runs/train/coco128/weights/best.pt \ format=onnx \ imgsz=640 \ device=0 Ultralytics 默认把 best.onnx 写在 .pt 同目录;脚本会再拷贝一份到: 1weights/best.onnx 方...















