首页 / 资讯中心 / 文章详情

swift自定义数据集微调Qwen-7B大模型,转换模型后使用ollama跑起来

swift自定义数据集微调Qwen-7B大模型,转换模型后使用ollama跑起来 ★ FEATURED ARTICLE
1. 从零跑通 swift 微调 Qwen-7B 再到 ollama 本地推理的完整链路如果你手里有一批自己的问答数据想让 Qwen-7B 学会你的说话风格或者业务知识最后还想在本地用 ollama 直接ollama run跑起来那这篇就是给你写的。swift 是魔搭社区开源的一套大模型微调框架能让你用几行命令完成 LoRA 微调ollama 则是本地推理最省心的工具之一。把这两件事串起来中间还差一个模型格式转换的环节很多人就是卡在 GGUF 转换和 Modelfile 上。我自己走这条路的时候踩过的坑主要集中在三块数据集格式写错导致 loss 不降、LoRA 合并后忘了导出完整权重、以及 ollama 的 Modelfile 模板和 Qwen 的 chat 格式对不上导致输出乱码。下面按顺序把每一步都拆开命令可以直接复制参数我会解释清楚为什么这么设。适合谁看有 Linux 环境、至少一张 16G 以上显存的卡、会基本的命令行操作想给自己的 Qwen-7B 喂自定义数据并落地到 ollama 的人。如果你还没装 CUDA 和 PyTorch建议先把基础环境弄好本文默认你已经能跑通nvidia-smi。整条链路是准备自定义数据集 → swift LoRA 微调 → swift infer 验证 → swift export 合并 LoRA → 转 GGUF → 量化 → 写 Modelfile → ollama create → ollama run。每一步都有可验证的结果不会让你走到最后才发现前面错了。2. TaoToken 前置准备给微调后的模型一个稳定的 API 出口微调完的模型除了本地 ollama 跑很多时候你还想把它接到自己的应用里或者和云端更强的模型做对比测试。这时候一个统一的 API 入口就很省事。TaoToken 提供的就是这样一个入口官网是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 地址是 https://taotoken.net/api 注意 API 地址后面不加 UTM 参数。为什么在微调流程里要提这个因为你在验证阶段经常需要「微调前 vs 微调后」的对比。本地 ollama 跑微调后的模型云端 API 跑原始 Qwen-7B两边同样的 prompt 一对比微调到底有没有生效一目了然。TaoToken 的模型对话页面可以直接做这种对比测试地址是 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 。如果你后面要把微调模型接进 Claude Code 或者做长期 coding agent可以看 coding planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。需要生成和管理 Key 的话在 consolehttps://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite API Keys 页面https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。这里要强调一点TaoToken 是合规的 API 聚合入口不是让你去搞什么灰色中转。你拿到的 Key 就是正常调用模型的凭证Base URL 填https://taotoken.net/apiModel ID 按文档里列出的填。三件套Base URL Key Model ID缺一不可后面在验证环节我会给出具体的调用示例。对于本文的主线——swift 微调 ollama 本地推理——TaoToken 主要用在两个地方一是微调前的 baseline 对比二是微调后如果你不想每次都本地加载模型可以用 API 方式快速验证效果。本地 ollama 适合离线、隐私敏感的场景API 适合快速迭代和对比。3. 可复制配置swift 微调 Qwen-7B 与数据集格式先说数据集。swift 支持本地 csv 文件格式就三列instruction、input、output。instruction 是你的问题input 是问题的背景补充没有就留空output 是期望的答案。我建议你至少准备 500 条以上太少的话模型学不到东西loss 会一直飘。一个最小可用的 csv 示例instruction,input,output 贝贝是谁,,贝贝是我养的一只橘猫今年三岁最喜欢在键盘上睡觉。 介绍一下我们的产品,,我们的产品是一款面向开发者的 API 聚合工具支持多种大模型统一调用。 怎么写一个 Python 的 hello world,,print(hello world) 就是最简单的写法注意 Python 3 里 print 是函数要加括号。注意 csv 里如果有逗号字段要用双引号包起来否则会解析错位。我建议用 pandas 生成而不是手写避免编码问题统一存成 UTF-8。然后是微调命令。多卡训练一定要加前面的环境变量否则默认只用一张卡慢到怀疑人生export MKL_THREADING_LAYERGNU \ CUDA_VISIBLE_DEVICES0,1,2,3 \ NPROC_PER_NODE4 \ swift sft \ --model_type qwen2-7b-instruct \ --model_id_or_path /root/.cache/modelscope/hub/qwen/Qwen2-7B-Instruct \ --sft_type lora \ --dtype AUTO \ --dataset /root/data/my_dataset.csv \ --self_cognition_sample 3000 \ --model_name 我的助手 \ --model_author 我的团队 \ --num_train_epochs 1 \ --lora_rank 8 \ --lora_alpha 32 \ --lora_dropout_p 0.05 \ --lora_target_modules ALL \ --gradient_checkpointing true \ --batch_size 1 \ --weight_decay 0.1 \ --learning_rate 1e-4 \ --gradient_accumulation_steps 16 \ --output_dir output几个关键参数解释一下。--dataset指向你的本地 csv 路径这是自定义数据集的核心。--lora_rank 8和--lora_alpha 32是 LoRA 的秩和缩放系数rank 越大能学的信息越多但显存占用也越高8 是个稳妥的起点。--lora_target_modules ALL表示对所有线性层加 LoRA效果通常比只加 qkv 好。--gradient_accumulation_steps 16配合batch_size 1等效 batch 是 16显存不够时的标准做法。训练过程中你会看到 loss 逐步下降正常情况从 2.x 降到 1.x 甚至更低。如果 loss 一直不降先检查数据集格式再看 learning_rate 是不是太大。训练完成后输出目录在output/qwen2-7b-instruct/vX-日期-时间/checkpoint-XX记下这个路径后面推理和合并都要用。4. 验证请求与成功结果推理、合并、转 GGUF、ollama 跑起来第一步用 swift infer 验证微调是否生效CUDA_VISIBLE_DEVICES0,1,2,3 swift infer \ --ckpt_dir output/qwen2-7b-instruct/v2-20240826-101129/checkpoint-48进入交互后问它一个你数据集里出现过的问题比如「贝贝是谁」。如果它能答出你训练数据里的答案说明微调生效了。这一步很关键别跳过否则后面转换完发现效果不对你都不知道是训练的问题还是转换的问题。第二步合并 LoRA 到基础模型CUDA_VISIBLE_DEVICES0,1,2,3 swift export \ --ckpt_dir output/qwen2-7b-instruct/v2-20240826-101129/checkpoint-48 \ --merge_lora true执行后会生成checkpoint-48-merged目录里面是完整的模型权重。LoRA 本身只是低秩矩阵必须合并后才能转 GGUF这一步不能省。第三步安装 ollama 并准备转换工具curl -fsSL https://ollama.com/install.sh | sh ollama serve然后拉取 ollama 源码注意要指定版本新版可能缺少 llama.cpp 子模块git clone -b v0.3.14 https://github.com/ollama/ollama.git cd ollama git submodule init git submodule update llm/llama.cpp编译量化工具python -m venv llm/llama.cpp/.venv source llm/llama.cpp/.venv/bin/activate pip install -r llm/llama.cpp/requirements.txt cd llm/llama.cpp/ make如果报错先装apt install cmake ccache。编译成功后目录下会有convert_hf_to_gguf.py和llama-quantize等工具。第四步转换模型为 GGUFpython ../ollama/llm/llama.cpp/convert_hf_to_gguf.py \ output/qwen2-7b-instruct/v2-20240826-101129/checkpoint-48-merged \ --outtype f16 \ --outfile converted.bin--outtype f16是不损失精度转换后大概 14G 左右。第五步量化到 4bit 减小体积../ollama/llm/llama.cpp/llama-quantize converted.bin quantized.bin q4_0量化后大概 4G 左右q4_0 是常用的 4bit 量化方案速度和精度平衡得不错。第六步写 ModelfileFROM quantized.bin PARAMETER temperature 0.7 PARAMETER top_p 0.8 PARAMETER repeat_penalty 1.05 TEMPLATE {{ if .System }}|im_start|system {{ .System }}|im_end| {{ end }}{{ if .Prompt }}|im_start|user {{ .Prompt }}|im_end| {{ end }}|im_start|assistant {{ .Response }}|im_end| SYSTEM You are a helpful assistant.第一行FROM quantized.bin必须和你的量化文件名一致这是最容易出错的地方。TEMPLATE 用的是 Qwen 的 chat 格式|im_start|和|im_end|不能写错否则输出会乱。第七步创建并运行ollama create test2 -f Modelfile ollama list ollama run test2ollama list能看到 test2 就说明创建成功ollama run test2进去问同样的问题对比微调前的输出如果答案更贴近你的数据集整条链路就通了。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth微调这条链路的报错和 API 调用不太一样但如果你在验证阶段用 TaoToken 做对比可能会遇到下面这些。401 Unauthorized这个基本是 Key 的问题。检查你的 API Key 有没有复制完整有没有多余空格。TaoToken 的 Key 在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 生成Base URL 填https://taotoken.net/api注意不要多加斜杠或者路径。如果还是 401去 console 确认 Key 的状态是否正常。local proxy failed这个报错通常出现在你本地配了代理但代理没起来或者环境变量HTTP_PROXY/HTTPS_PROXY指向了一个不可用的地址。解决办法是先unset HTTP_PROXY HTTPS_PROXY再重试。注意这里说的是清理环境变量不是让你去搞什么网络工具纯粹是本地环境配置问题。reading choices 报错这个一般出现在你调用 API 后解析返回结果时返回体里没有choices字段。原因可能是请求格式不对比如 model 名字写错、messages 格式不对。检查你的请求体确保model字段和文档里的一致messages是标准的 role/content 结构。OAuth 相关报错如果你在用 Claude Code 或者类似的工具接入可能会遇到 OAuth 认证失败。这时候检查你的配置文件Claude Code 的 settings 里 Base URL 和 Key 要配对。如果是 Codex 的 auth.json格式是这样的{ base_url: https://taotoken.net/api, api_key: 你的Key, model: 文档里列出的Model ID }三件套 Base URL、Key、Model ID 必须同时正确缺一个都会报错。Cline 的 MCP 配置也是同理在 settings 里把这三项填对。另外微调本身常见的坑数据集 csv 编码不是 UTF-8 导致读进来乱码、LoRA 合并时忘了加--merge_lora true导致导出的还是适配器、GGUF 转换时模型路径写错、Modelfile 里 FROM 的文件名和实际量化文件名不一致。这些都会让最后ollama run出问题建议每步都验证一下输出文件是否存在、大小是否合理。6. 把微调模型接进你的工作流API 与本地推理的配合整条链路跑通后你手里其实有两个东西一个是本地 ollama 里的微调模型一个是 TaoToken 提供的云端 API 入口。这两个不是二选一而是配合使用。本地 ollama 适合数据隐私敏感、需要离线、频繁调用不想花 token 的场景。微调后的模型在本地跑响应速度取决于你的显卡7B 的 q4 量化在消费级卡上基本能到可用水平。TaoToken API 适合快速对比测试、需要调用更大模型、做 agent 或者 coding 辅助的场景。你可以用 API 跑原始 Qwen-7B 作为 baseline和本地微调模型对比验证微调效果。模型对话入口在 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。如果你要把微调模型接进 Claude Code 做长期编码辅助可以看 coding planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。Claude Code 的 Anthropic 接入配置在 https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaude_codeutm_campaignrewrite 里面有具体的 Base URL 和 Key 配置方式。最后给一个实用建议微调数据集的质量比数量重要。我试过用 200 条精心构造的数据效果比 2000 条随便爬的数据好得多。每条数据的 output 要准确、风格一致instruction 要覆盖你实际会问的问题类型。训练完先用 swift infer 验证再走转换流程别一上来就全套跑完才发现数据有问题。
阅读完成 · 觉得有帮助?
咨询建站