插图:用一份私有数据集在租用的 GPU 服务器上微调语言模型

在租用的 GPU 上私密微调 LLM:实用指南

什么时候微调比 RAG 或改提示词更合适,各尺寸模型的 QLoRA 显存需求,TRL、Unsloth 和 Axolotl,在租用 GPU 上保护数据隐私,以及成本和部署。

用 QLoRA 在你自己的数据上微调一个 8B 开放权重模型,一块租来的 24 GB GPU 就够,一次典型的训练花费不到一美元。更难的问题要先回答:微调到底是不是对的办法(要补充事实,通常检索更好),以及数据放在别人的机器上时,怎样保证它不外泄。

本文先讲这两点,再讲各尺寸模型需要的显存、当前的工具、一个能跑的训练脚本、一个成本算例,以及怎样部署训练结果。所有内容均于 2026 年 9 月核实,出处附在文末。

微调、RAG 还是改进提示词

微调改变的是模型的行为,拿它来教模型事实效果很差。Ovadia 等人比较了两者在知识注入方面的表现,发现 RAG“一直优于”无监督微调,“无论是训练中见过的已有知识,还是全新的知识”。他们的结论是:LLM 很难通过微调学到新事实。

所以租任何东西之前,先把下面这棵决策树走一遍:

决策树:在检索、改进提示词、微调和更大的模型之间做选择 回答不够好 缺少事实,或者数据经常变化? 用 RAG 每次请求时检索你的文档 是 否 指令和示例能解决吗? 改进提示词 系统提示词、少样本示例 是 否 需要固定的格式、语气或技能? 用 QLoRA 微调 几百条高质量样本 是 否 换一个更大的基础模型 RAG 和微调可以结合使用: 行为靠微调,事实靠检索
大多数“模型不了解我们的东西”的问题,其实是检索问题。当你需要每次都一样的行为时,微调才物有所值:固定的 JSON schema、公司的文风、一套分类方案。

值得微调的理由:

  • 严格的输出格式。 每次调用都把字段按你的 schema 提取出来,而不用在每条提示词里塞一页说明。
  • 风格和语气。 让客服回复听起来像你的团队写的,或者让报告保持固定结构。
  • 用小模型做窄任务。 一个调过的 8B 模型可以在某一项工作上替代大型通用模型,在廉价硬件上部署时这一点很重要。
  • 更短的提示词。 学进权重里的行为,不用在每次请求中重复。

LoRA 和 QLoRA

全量微调会更新所有权重,所以 GPU 除了模型本身,还要为每个权重存梯度和优化器状态。LoRA 冻结基础模型,在各层旁边训练小的低秩矩阵;原始论文报告,与用 Adam 全量微调 GPT-3 175B 相比,可训练参数减少了 10,000 倍,显存占用减少到三分之一。

QLoRA 更进一步:冻结的基础模型以 4 位 NF4 精度加载,只有适配器以 16 位训练。Dettmers 等人用它在一块 48 GB GPU 上微调了 65B 模型,“同时保持了 16 位全量微调的任务表现”。论文引入了三样工具至今仍在用的东西:NF4 数据类型、对量化常数的二次量化,以及用来吸收显存峰值的分页优化器。

两者的产物都是一个适配器,一个装着几个张量的文件夹,叠加在未改动的基础模型上使用。你可以让它单独存在,也可以合并进权重。图像模型用的也是同样的方法:一个Stable Diffusion LoRA在一张租来的 24 GB 显卡上就能训练,花费远低于 $10。

需要多少显存

Unsloth 发布了一张按模型尺寸列出微调最低显存的表格。下面是它的数字,已包含它的显存优化;普通的 Hugging Face 训练需要更多,序列更长或批次更大时,每一行都会上升。

模型尺寸QLoRA(4 位)LoRA(16 位)跑 QLoRA 绰绰有余的租用显卡
3B3.5 GB8 GB任何 12 GB 以上的显卡
8B6 GB22 GBRTX 3090 / 4090(24 GB)
14B8.5 GB33 GBRTX 3090 / 4090(24 GB)
32B26 GB76 GB48 GB 显卡(RTX A6000、A40、L40S)
70B41 GB164 GB80 GB 显卡(A100、H100)
条形图:8B、14B、32B 和 70B 模型用 QLoRA 和 16 位 LoRA 微调的最低显存,对照 24、48 和 80 GB 显卡 QLoRA 4 位 LoRA 16 位 24 GB 48 GB 80 GB 8B 6 22 14B 8.5 33 32B 26 76 70B 41 164 0 40 80 120 160 最低显存,单位 GB(Unsloth 需求表)
正是 QLoRA 让租来的消费级显卡在这里派上用场:14B 以内的模型放进 24 GB 显卡还有富余,32B 需要 48 GB 显卡,70B 需要 80 GB。不用 4 位加载的话,连 8B 在 24 GB 里都很勉强。

我的默认选择是在 RTX 4090 上跑 8B 或 14B 模型。这是能为 2,048 token 序列和合理批次留出空间的最便宜的租用显卡,而且这个范围的模型事后也容易部署。按部署用的显存选基础模型,见哪些 AI 模型适合你的 GPU 显存。

选工具:TRL、Unsloth 还是 Axolotl

三个都是开源的,都支持 LoRA 和 QLoRA。

工具用法优势注意
Hugging Face TRL + PEFTPython(SFTTrainer)参考实现;同一套 API 还支持 DPO、GRPO 等同样的训练,显存占用比 Unsloth 多
UnslothPython,或 Unsloth Studio 网页界面号称快 2 倍、显存少 70%;可直接导出 GGUFStudio 界面采用 AGPL-3.0(核心为 Apache 2.0)
Axolotl一个 YAML 文件,axolotl train config.yml多 GPU(FSDP、DeepSpeed),配方丰富需要 Python 3.11+ 和 PyTorch 2.11+

截至 2026 年 9 月,TRL 版本为 1.14,PEFT 为 0.21。Unsloth 需要 Python 3.11 到 3.13,以及 CUDA 计算能力 7.0 或更高的 NVIDIA GPU(V100、T4、RTX 20 系列及以上)。Axolotl 推荐 Python 3.12 和 PyTorch 2.12.1。

想弄懂每一行代码,用 TRL;显存紧张或想一次调用就导出 GGUF,用 Unsloth;要用不同设置反复训练或者要上多 GPU,用 Axolotl。下面的脚本用的是 TRL,因为它是把每个环节都摆在明面上的最短路径。

准备数据

TRL 的 SFTTrainer 读取的对话格式和聊天 API 请求一样。train.jsonl 里每行一个 JSON 对象:

{"messages": [{"role": "system", "content": "Extract the invoice fields as JSON."}, {"role": "user", "content": "Invoice 4471 from Norden AB, due 12 March, total 1,250 EUR"}, {"role": "assistant", "content": "{\"invoice_id\": \"4471\", \"supplier\": \"Norden AB\", \"due\": \"2026-03-12\", \"total\": 1250, \"currency\": \"EUR\"}"}]}

几条实用原则:

  • 质量重于数量。 几百到几千条一致、正确的样本,胜过几万条噪声数据。数据里的每个错误,都是你花钱教给模型的行为。
  • 与生产环境一致。 使用你的应用实际会发送的系统提示词和输入格式。
  • 留出 5% 到 10%。 保留一部分模型从未训练过的样本,用来并排比较基础模型和调过的模型。
  • 删掉用不上的东西。 姓名、邮箱、账号和各种 ID 很少能帮模型学会格式。数据离开你的电脑之前,把它们换成逼真的占位符。

最后一条不仅仅关乎租来的机器。Carlini 等人从 GPT-2 中逐字提取出了数百条训练序列,包括姓名、电话号码和邮箱地址,其中有些只在一份训练文档中出现过。微调后的模型可能会把训练内容复述给之后使用它的任何人。

在租来的机器上保护数据隐私

在 GPU 市场上,电脑归别人所有。Vast.ai 说得很直白:“客户被隔离在非特权 Docker 容器中,只能访问自己的数据”,以及“各提供商的安全水平差别很大”。这种隔离保护你不受其他租用者影响,但防不了能接触到物理机器、在主机上拥有 root 权限的人。

处理私密数据时:

  1. 选择经过审核的数据中心主机。 Vast.ai 的 Secure Cloud 提供商是“通过 ISO 27001 认证、符合 Tier 3/4 数据中心标准的经审核数据中心”,Vast 建议敏感任务使用它们。RunPod 的 Secure Cloud 运行在 T3/T4 数据中心;其 Community Cloud 则把你连接到个人提供商。数据中心层级每小时更贵,但在这里值得。
  2. 只上传清理过的数据集, 走 SSH(rsync -avP 或 scp)。中途不要放到公开存储桶或共享链接里。
  3. 日志只留在本地。 在 TRL 1.14 中,report_to 默认为 "none",所以除非你主动开启,否则不会有数据发往实验追踪服务。不要对用私密数据训练出的适配器调用 push_to_hub。
  4. 把结果拿出来,然后删除实例。 下载适配器和评估输出;如果用过令牌,退出 Hugging Face 登录(hf auth logout);删除实例和所有卷。在 Vast.ai 上,存储会一直保留并计费,直到实例被删除,仅停止是不够的。

在容器里删除文件,并不能保证主机的磁盘被擦除,所以真正的保护在第 1 步和第 2 步:选好由谁掌管硬件,并且尽量少给对方数据。更多细节见如何在公共 GPU 节点上保护数据集。如果你的政策禁止使用任何第三方硬件,同样的脚本也能在你自己的 24 GB 显卡上运行。

训练:一个用 TRL 的 QLoRA 脚本

在一台装有 RTX 3090 或 4090 的租用 Linux 机器上:

python -m venv venv && source venv/bin/activate
pip install torch trl peft bitsandbytes datasets

然后是 train.py,照着 TRL 的 PEFT 文档中的 QLoRA 写法。Qwen3-8B 采用 Apache 2.0 许可证,无需申请访问,所以不需要 Hugging Face 令牌:

import torch
from datasets import load_dataset
from peft import LoraConfig
from transformers import BitsAndBytesConfig
from trl import SFTConfig, SFTTrainer

dataset = load_dataset("json", data_files="train.jsonl", split="train")

bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_compute_dtype=torch.bfloat16,
    bnb_4bit_use_double_quant=True,
)

peft_config = LoraConfig(
    r=16,
    lora_alpha=32,
    lora_dropout=0.05,
    target_modules="all-linear",
    task_type="CAUSAL_LM",
)

args = SFTConfig(
    output_dir="out",
    num_train_epochs=3,
    per_device_train_batch_size=4,
    gradient_accumulation_steps=4,
    learning_rate=2e-4,
    lr_scheduler_type="cosine",
    warmup_steps=20,
    max_length=2048,
    bf16=True,
    logging_steps=10,
    save_strategy="epoch",
    model_init_kwargs={"dtype": torch.bfloat16},
)

trainer = SFTTrainer(
    model="Qwen/Qwen3-8B",
    args=args,
    train_dataset=dataset,
    quantization_config=bnb_config,
    peft_config=peft_config,
)
trainer.train()
trainer.save_model("out/adapter")

要紧的几个选择:

  • learning_rate=2e-4。 TRL 文档建议 QLoRA 使用约为常规微调 10 倍的学习率。如果训练损失下降而评估损失上升,就是过拟合了:减少轮数。
  • r=16,target_modules="all-linear"。 在每个线性层上加适配器,这也是 Unsloth 基准测试使用的设置。对格式和风格来说,秩 16 就够了;任务更难时再调高。
  • max_length=2048。 更长的样本会被截断。检查一下数据的 token 长度;上限越长,需要的显存越多。
  • 有效批大小 16(4 × 4 个累积步)。如果显存不够,调低 per_device_train_batch_size、调高累积步数,保持乘积不变。

关机之前,把留出的样本分别交给基础模型和调过的模型,比较一下结果。只有这个测试能告诉你这笔钱有没有花出效果。

要花多少钱

训练时间等于总 token 数除以吞吐量。托管公司 GigaGPU 公布了实测数据:在 RTX 4090 上用 QLoRA 训练 Llama 3.1 8B,约每秒 3,500 个训练 token。假设 Qwen3-8B 的速度相近:

小规模训练: 2,000 条样本 × 600 token × 3 轮 = 360 万 token。3,600,000 ÷ 3,500 = 1,029 秒,约 17 分钟。

步骤时间
搭建环境10 分钟
下载 Qwen3-8B(16.4 GB 权重)并上传数据10 分钟
训练17 分钟
在留出数据上比较基础模型和调过的模型15 分钟
合并、导出、下载,删除实例15 分钟
合计67 分钟(1.12 小时)
  • Vast.ai RTX 4090,每小时 $0.31:1.12 × $0.31 = $0.35
  • RunPod RTX 4090,每小时 $0.74(价格页面标价):1.12 × $0.74 = $0.83

大规模训练: 20,000 条样本 × 1,000 token × 2 轮 = 4,000 万 token ÷ 3,500 = 11,429 秒,约 3.2 小时。加上同样的 50 分钟额外时间,共 4.0 小时:Vast.ai 上 $1.24,RunPod 上 $2.97。

对于 32B 模型,截至 2026 年 9 月,RunPod 上 48 GB 显卡的标价为每小时 $0.49(A40)、$0.53(RTX A6000)和 $1.09(L40S)。我没有找到这些显卡上 32B QLoRA 的公开吞吐数据,所以先跑 50 步,从日志里读出每步耗时,做同样的乘法,再决定要不要跑长时间的训练。

价格为 2026 年 9 月的数字,来自 RunPod 价格页面和 getdeploying.com 对 Vast.ai 的价格追踪。Secure/数据中心层级比最便宜的社区报价贵。更全面的情况见 GPU 租用价格对比。

部署训练结果

有两种选择:让适配器单独存在,或者把它合并进模型。

用 vLLM 单独加载。 vLLM 可以在基础模型旁边加载 LoRA 适配器,并在其 OpenAI 兼容服务器上把每个适配器暴露为一个模型名:

vllm serve Qwen/Qwen3-8B --enable-lora --lora-modules invoices=./out/adapter

客户端发送 "model": "invoices" 即可。多个适配器可以在一块 GPU 上共用一个基础模型。

合并后在 Ollama 中运行。 把适配器合并进全精度权重,用 llama.cpp 转换为 GGUF,量化,然后导入:

import torch
from peft import AutoPeftModelForCausalLM
from transformers import AutoTokenizer

model = AutoPeftModelForCausalLM.from_pretrained("out/adapter", dtype=torch.bfloat16)
model.merge_and_unload().save_pretrained("merged")
AutoTokenizer.from_pretrained("Qwen/Qwen3-8B").save_pretrained("merged")
python llama.cpp/convert_hf_to_gguf.py merged --outfile invoices-bf16.gguf --outtype bf16
./llama.cpp/build/bin/llama-quantize invoices-bf16.gguf invoices-Q4_K_M.gguf Q4_K_M
echo "FROM ./invoices-Q4_K_M.gguf" > Modelfile
ollama create invoices -f Modelfile

Unsloth 一次调用就能完成合并和 GGUF 导出(model.save_pretrained_gguf("dir", tokenizer, quantization_method="q4_k_m"))。它的文档提醒,导出后回答质量变差,最常见的原因是聊天模板不对:部署时要用训练时的模板。Ollama、vLLM 和 TGI 之间的取舍见我们的 RTX 4090 推理基准测试。

GPUFlow 在其中的位置

GPUFlow 做不了训练:它出租的是运行在提供商 GPU 上的 OpenAI 兼容 API,没有 shell、SSH,也不能访问文件。它也不能部署你微调好的模型。租用者不能上传模型;可用的模型是各提供商自己安装的(通常用 Ollama),例如 qwen2.5:7b 或 llama3.1:8b。

它能帮上忙的是这一切之前的那一步:花几美分检查一下,一个现成的开源模型配上好的提示词是否已经能胜任,这是决策树里最便宜的结果。这一步请用测试数据,不要用本文讨论的私密数据:租用期间,提示词和回答以明文经过提供商的机器。具体用法见 API 快速入门,在应用中使用 API 密钥介绍了怎样把它接入现有工具。

资料来源

均于 2026 年 9 月核实。

常见问题

微调 7B 或 8B 模型需要多少显存?

用 QLoRA 时,Unsloth 的需求表列出 7B 模型约需 5 GB、8B 模型约需 6 GB;普通的 16 位 LoRA 分别约需 19 GB 和 22 GB。实际训练要为更长的序列和更大的批次留出余量,所以 RTX 3090 或 4090 这类 24 GB 显卡是宽裕的选择。

该用微调还是 RAG?

模型需要你文档里的事实,尤其是会变化的事实时,用 RAG。Ovadia 等人 2024 年的研究发现,在补充知识方面,RAG 一直优于无监督微调。当你需要稳定的格式、语气或窄任务行为,而提示词又做不到稳定时,再微调。

在租用的 GPU 上微调 LLM 要花多少钱?

用 2,000 条样本对 8B 模型做一次 QLoRA 训练,连同准备工作一个多小时:在每小时 $0.31 的 Vast.ai RTX 4090 上约 $0.35,按 RunPod 每小时 $0.74 的标价约 $0.83(2026 年 9 月)。20,000 条样本的训练约需四小时,即 $1.24 到 $2.97。

GPU 主机能看到我的训练数据吗?

硬件归主机所有,所以要假定对方能看到。容器隔离保护你不受其他租用者影响,但防不了机器的主人。敏感数据请使用经过审核的数据中心主机(Vast.ai Secure Cloud、RunPod Secure Cloud),上传前删掉个人数据,用完后删除实例。

LoRA 和 QLoRA 有什么区别?

LoRA 冻结基础模型,只训练小的适配器矩阵。QLoRA 做法相同,但把冻结的基础模型以 4 位 NF4 精度加载;在原始论文中,这让显存省到了能在一块 48 GB GPU 上微调 65B 模型的程度。

能在 GPUFlow 上微调或上传自己的模型吗?

不能。GPUFlow 只做推理:你租用的是 OpenAI 兼容聊天 API,背后是提供商在自己机器上安装的模型,通常用 Ollama 运行。没有 shell,也不能访问文件,所以既不能在上面训练,也不能上传自己的模型。