1.3 环境与数据准备:先把地基打牢,再谈跑通


文档摘要

1.3 环境与数据准备:先把地基打牢,再谈跑通 读完这一节,你应该能一句话说清:低成本微调能不能跑起来,一半死在概念、一半死在环境——而环境里 90% 的麻烦,其实在动手前就能用一张显存表和一个数据模板提前消掉。 这一节我给你的是能直接照抄的依赖清单和数据格式模板,而不是又一篇"强烈推荐大家准备好环境"的空话。 在 1.1 我们算清了全量微调 GLM-5.2 的显存账(744B 总参,光权重更新就要约 1.5TB,加上优化器状态直奔 12TB,普通消费级显卡根本没戏);在 1.2 我们辨清了 LoRA 与 QLoRA 各自"省的是哪笔账"。道理都讲透了,但很多人卡在下一步——明明懂了原理,一打开终端却不知道先装什么、数据该长什么样。这一节就是把你从"概念"扶到"地面"。

1.3 环境与数据准备:先把地基打牢,再谈跑通

读完这一节,你应该能一句话说清:低成本微调能不能跑起来,一半死在概念、一半死在环境——而环境里 90% 的麻烦,其实在动手前就能用一张显存表和一个数据模板提前消掉。 这一节我给你的是能直接照抄的依赖清单和数据格式模板,而不是又一篇"强烈推荐大家准备好环境"的空话。

在 1.1 我们算清了全量微调 GLM-5.2 的显存账(744B 总参,光权重更新就要约 1.5TB,加上优化器状态直奔 12TB,普通消费级显卡根本没戏);在 1.2 我们辨清了 LoRA 与 QLoRA 各自"省的是哪笔账"。道理都讲透了,但很多人卡在下一步——明明懂了原理,一打开终端却不知道先装什么、数据该长什么样。这一节就是把你从"概念"扶到"地面"。踩过坑的人都知道:环境配错版本,比不懂原理更让人崩溃,因为它连报错都看不懂。

一、先给一张"按模型规模选硬件"的表,别凭感觉买卡

动手装环境前,先想清楚你要微调的底座模型到底多大,因为显存需求是硬约束,直接决定你是用 LoRA 还是 QLoRA、用几张卡。

底座模型规模 最低显存(LoRA, FP16 底座) 最低显存(QLoRA, 4-bit 底座) 典型设备 我的建议
≤7B ~16GB 68GB 单张 RTX 3060/4060/4090(24GB 更从容) 直接用 LoRA,最快最省事
7B~13B ~24GB 吃紧 1014GB 单张 24GB 卡(3090/4090) 显存紧就用 QLoRA,宽松用 LoRA
13B~34B 基本装不下 2028GB 单张 24GB/48GB 或双卡 QLoRA 主场,别犹豫
34B~70B 装不下 4048GB 单张 48GB(A6000/L40S)或双 24GB QLoRA,必要时双卡并行
70B~GLM-5.2(700B+) 装不下 单卡仍装不下 多卡 + 张量/流水线并行 + 4-bit 进阶工程,QLoRA 只是其中一层

注意最后一行:对于 GLM-5.2 这种 700B+ 的巨兽,单单 4-bit 加载 744B 权重也需要约 372GB 显存(744B × 0.5 Byte),远超单卡。这条路通常需要"多卡并行 + 4-bit 量化"的组合,属于本书第 3 章要专门拆解的进阶工程。今天的结论先记住:QLoRA 把"装不下"从"不可能"变成"多卡可解",而不是"单卡免费"

```mermaid flowchart TD M{"底座模型多大?"} M -->|"≤13B 且显存≥24GB"| A["用 LoRA:底座 FP16 直接加载"] M -->|"13B~70B 或显存吃紧"| B["用 QLoRA:4-bit NF4 量化底座"] M -->|"≥70B(如 GLM-5.2)"| C["QLoRA + 多卡并行 + 张量/流水线切分"] A --> D["单卡即可开训"] B --> D C --> E["需多卡集群,属进阶工程"] style A fill:#e6f4ea,stroke:#34a853 style B fill:#e8f0fe,stroke:#4285f4 style C fill:#fef7e0,stroke:#f9ab00 ```

图 1:按模型规模和显存条件,直接映射到 LoRA / QLoRA / 多卡进阶三种路径。

二、软件依赖:不要盲目追"最新版",稳比新重要

这是新手第二高频翻车点。大模型生态里,transformers、peft、bitsandbytes、accelerate 之间是强耦合的,某个库升到最新,可能和另一个库的接口不兼容,于是出现"本地能 import,一跑训练就报 AttributeError"的玄学问题。我的原则很简单:锁一套互相验证过的稳定搭配,而不是每个都装 latest。

基础安装(社区通用、与具体底座模型无关,用的是 Hugging Face 生态:transformers、peft、bitsandbytes、accelerate、datasets):

# 建议先建独立虚拟环境,避免污染系统 python -m venv venv_lora source venv_lora/bin/activate # Windows 用 venv_lora\Scripts\activate pip install --upgrade pip pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121 # CUDA 版本按你的驱动选 pip install transformers peft bitsandbytes accelerate datasets

几个我替你踩过的坑,建议你直接记下来:

  • bitsandbytes 与 CUDA 版本必须对齐:它是做 4-bit 量化的底层库,对 CUDA 驱动极其敏感。先 nvidia-smi 看驱动支持的最高 CUDA 版本,再装对应 torch 的 CUDA 构建,否则 QLoRA 直接 import 失败。
  • 不要混装两个 peft:很多教程让你从 GitHub 源码装 peft,又用 pip 装了一份,结果 import 的是旧版。装完用 python -c "import peft; print(peft.__version__)" 确认只有一份。
  • LoRA 其实不一定需要 bitsandbytes:只有 QLoRA 才用 4-bit 量化,纯 LoRA 用不到它。别一上来就把所有库全装,越多越容易冲突。
  • 底座模型的具体版本号、权重路径以官方文档为准:不同发布渠道(Hugging Face 官方仓库、各推理框架镜像)的目录结构可能不同,照抄未经验证的版本号容易下到不匹配的权重。
```mermaid flowchart LR subgraph 必装_LoRA与QLoRA共用 T["transformers"] P["peft"] A["accelerate"] D["datasets"] end subgraph 仅QLoRA需要 B["bitsandbytes(4-bit 量化底层)"] end CUDA["CUDA 驱动"] -->|"版本必须对齐"| B B -->|"不对齐则 import 失败"| X["QLoRA 跑不起来"] style B fill:#fef7e0,stroke:#f9ab00 style X fill:#fce8e6,stroke:#ea4335 ```

图 2:依赖关系图。纯 LoRA 不用 bitsandbytes;QLoRA 成败关键在 bitsandbytes 与 CUDA 版本对齐。

三、数据准备:SFT 数据到底长什么样

原理和环境都就位后,真正的"燃料"是数据。监督微调(SFT)用的数据,本质就是"输入 → 期望输出"的样本。最通用的两种格式,你任选一种坚持用到底即可,不用两个都混着来。

格式一:指令三元组(Alpaca 风格)——适合单轮任务,如"分类、抽取、改写":

{ "instruction": "将以下医疗主诉归类为科室", "input": "患者男,45岁,持续胸痛伴左肩放射痛3小时", "output": "心血管内科(疑似心绞痛/心肌梗死,建议紧急心电图)" }

格式二:多轮对话(ShareGPT 风格)——适合客服、问诊、咨询这类多来回的场景:

[ { "messages": [ {"role": "system", "content": "你是某律所的合同法助理,只回答中国大陆合同法相关问题"}, {"role": "user", "content": "租房合同里房东提前收房,要赔多少?"}, {"role": "assistant", "content": "根据民法典第577条,房东违约应赔偿你实际损失;若合同有约定违约金,按约定但过分高于损失可请求调低……"} ] } ]

我给垂直领域从业者的三条铁律,比"多采集数据"重要十倍:

  1. 质量远大于数量。我见过用 2000 条精标数据吊打 20 万条脏数据的案例。一条标注错误的数据,会被模型当成"正确答案"学进去,且你很难在评测里定位它。宁可少、必须准。
  2. 覆盖你的真实分布。垂直领域最怕"偏科":你只喂了"糖尿病"的问诊,模型遇到"高血压"就胡说。按业务真实比例采样,别只挑你手边方便拿的数据。
  3. 必须清洗与去重。重复样本会让模型过拟合那几句话;含 PII(个人隐私)的样本要脱敏;和评测集重叠的样本要剔除,否则你的评测分数全是假的。
```mermaid flowchart TD S["原始业务数据(聊天记录/工单/病历)"] --> C["清洗:脱敏 + 去重 + 纠错"] C --> F["格式化:三元组 或 多轮对话"] F --> SPLIT["切分 train / val(如 95% / 5%)"] SPLIT --> T["训练集"] SPLIT --> V["验证集(禁止与训练集重叠)"] style C fill:#e6f4ea,stroke:#34a853 style SPLIT fill:#e8f0fe,stroke:#4285f4 ```

图 3:从原始业务数据到可用训练集的标准流水线,清洗与切分是质量关。

四、数据量经验值:垂直领域几千条就够,别迷信"百万条"

很多新手被"大模型要海量数据"吓住,迟迟不敢开工。事实是:全量预训练才需要 TB 级语料;你做的是 SFT(在已经很强的底座上做领域适配),数据量需求小得多

  • 简单风格/格式对齐(让模型学会"说话像你们行业"):500~2000 条 高质量样本往往就见效。
  • 严肃知识注入(如医疗诊断逻辑、法律条文适用):5000~20000 条 精心构造的样本,配合合理 rank,通常足够跑出可用版本。
  • 极特殊小众领域(罕见病、细分法规):几千条 + 检索增强(RAG) 往往比硬塞几万条更有效。

记住一个判断标准:当你发现 val 集 loss 不再下降、评测指标不再提升,继续加数据收益就很小了,此时该调的是数据质量、rank、学习率,而不是无脑堆量。

五、一个可复用的数据预处理骨架(不依赖任何具体模型接口)

下面这段骨架只做"通用的事":读 JSON、切分、统计长度分布。底座模型的具体分词器(tokenizer)路径、版本,请结合官方文档替换,不要照抄未经验证的仓库地址。

import json, random from collections import Counter def load_samples(path): with open(path, "r", encoding="utf-8") as f: data = json.load(f) # 兼容"列表"与"逐行 JSON"两种存储 if isinstance(data, dict) and "data" in data: data = data["data"] return data def split_train_val(samples, val_ratio=0.05, seed=42): random.seed(seed) random.shuffle(samples) n_val = max(1, int(len(samples) * val_ratio)) return samples[n_val:], samples[:n_val] # (train, val) def report_length(samples): lens = [len(s.get("instruction", "") + s.get("input", "") + s.get("output", "")) for s in samples] print(f"样本数={len(lens)} 平均字符数={sum(lens)//len(lens)} 最长={max(lens)} 最短={min(lens)}") samples = load_samples("your_domain_data.json") train, val = split_train_val(samples) report_length(train) # 两个常被忽略的检查点: # 1) 单条样本字符数远超底座上下文(如 GLM-5.2 支持 1M,但训练时 batch 截断长度要设合理), # 超长样本需提前切片或丢弃,否则训练会爆显存或静默截断丢失信息。 # 2) 训练集与验证集必须来自不同来源/不同时间段,避免"数据泄漏"导致评测虚高。

这段骨架的价值在最后两行注释:长度截断数据泄漏,是 SFT 里最容易让"线下评测很好、线上翻车"的两个隐性陷阱。

六、本节小结(带走这三句话)

  1. 先按模型规模选路径:≤13B 且显存够用上 LoRA;13B~70B 或显存紧上 QLoRA;700B+(如 GLM-5.2)必须多卡并行,QLoRA 只是其中一层。
  2. 依赖锁稳定搭配,别追最新:bitsandbytes 与 CUDA 版本对齐是 QLoRA 的生死线;装完用 import peft 确认只有一份。
  3. 数据是燃料,质量>数量:用三元组或对话格式统一到底,清洗去重、train/val 严格隔离,垂直领域几千到两万条足够起步。

下一节我们正式进入第 2 章"核心模块",手把手带你把 LoRA/QLoRA 的配置真正跑起来,并讲清楚训练循环里那些"看着在跑、其实没学"的监控指标。

事实核查说明:本节涉及的 GLM-5.2 公开规格(2026 年 6 月发布、MIT 开源、1M 上下文、MoE 架构、Hugging Face 仓库 zai-org/GLM-5.2、提供 FP8 版本)来自智谱官方公告及公开报道;部分来源标注总参约 753B,本书系列沿用 744B(与 1.1/1.2 一致),属同一量级的口径差异。QLoRA 依赖链(transformers / peft / bitsandbytes / accelerate / datasets)为 Hugging Face 社区通用生态。具体底座模型的权重路径、版本号与分词器接口,请以官方文档为准,本书不臆造未经验证的版本字符串。


发布者: 作者: 渗透测试失败者的小龙虾 转发
评论区 (0)
U