基座模型用通用语料训练网页、书籍、代码但你的业务数据可能是医疗、法律、金融——领域词不在词表里模型答不准。持续预训练Continued Pre-Training用领域数据继续训练基座模型扩展词表和专业能力。持续预训练 vs 微调维度持续预训练微调SFT/LoRA数据量10M-1B tokens10K-1M tokens训练目标MLM/CLM无监督指令跟随有监督词表可扩展不扩展训练时间数天到数周数小时到数天效果领域知识内化指令跟随能力持续预训练是给模型补知识微调是教模型怎么用知识回答问题。数据准备领域数据需要跟预训练数据同分布纯文本无指令格式# 错误带指令格式这是 SFT 数据{instruction:解释心绞痛,input:,output:...}# 正确纯文本跟预训练一样{text:心绞痛是由于冠状动脉供血不足引起的胸痛...\n\n病理机制...}数据量建议领域最小数据量推荐数据量医疗100M tokens1B tokens法律50M tokens500M tokens金融50M tokens500M tokens代码100M tokens2B tokens训练配置fromtransformersimportTrainer,TrainingArguments training_argsTrainingArguments(per_device_train_batch_size4,gradient_accumulation_steps32,# 有效 batch 4×32 128max_seq_len4096,learning_rate1e-5,# 持续预训练用较小的 LRweight_decay0.01,num_train_epochs3,# 领域数据少的话 1-2 轮就够了save_steps1000,fp16False,bf16True,# 昇腾NPU 推荐 bf16deepspeedds_config_zero3.json,# ZeRO-3 节省显存...)trainerTrainer(modelmodel,argstraining_args,train_datasetdataset)trainer.train()学习率关键持续预训练的 LR 应该比预训练小 10-100×。预训练 LR 通常是 1e-4 到 3e-4持续预训练用 1e-5 到 3e-5。词表扩展领域专有词如医疗的阿司匹林肠溶片被拆成多个 subword模型难以理解。扩展词表fromsentencepieceimportSentencePieceTrainer# 1. 在领域数据上训练新词表SentencePieceTrainer.train(inputdomain_corpus.txt,model_prefixdomain_bpe,vocab_size5000,# 扩展 5000 个新词model_typebpe,)# 2. 扩展模型词表model.resize_token_embeddings(old_vocab_size5000,pad_to_multiple_of64,# 对齐到 64Cube 要求)扩展后的新词 embedding 用旧词 embedding 的平均值初始化然后在持续预训练中更新。防止灾难性遗忘持续预训练容易让模型忘记通用能力。解决方案方案 1混合通用数据# 90% 领域数据 10% 通用数据mixed_datasetconcatenate_datasets([domain_dataset.shuffle().select(range(int(0.9*len(domain_dataset)))),general_dataset.shuffle().select(range(int(0.1*len(domain_dataset))),])方案 2较小的学习率LR1e-5 比 LR1e-4 的遗忘少 30-50%。方案 3LoRA 持续预训练# 只用 LoRA 更新参数原模型冻结modelget_peft_model(model,lora_config)# 持续预训练时只更新 LoRA 参数原模型参数不变不会遗忘。昇腾NPU 上的加速持续预训练数据量大10M-1B tokens需要分布式训练# 8 卡 Atlas 800I A2training_argsTrainingArguments(...,deepspeedds_config_zero3.json,# ZeRO-3tf32True,# 昇腾NPU 支持 TF32等价 fp32 精度fp16 速度)ZeRO-3 把优化器状态、梯度、参数都分片到各卡8 卡Llama2-7B 无 ZeRO: 每卡显存 76GBOOM ZeRO-1: 每卡显存 42GB ZeRO-2: 每卡显存 28GB ZeRO-3: 每卡显存 18GB ← 8 卡都能跑效果评估持续预训练后在领域任务和通用任务上分别评估# 领域任务医疗问答domain_scoreevaluate(model,medical_qa_dataset)# 通用任务MMLUgeneral_scoreevaluate(model,mmlu_dataset)print(f领域得分:{domain_score:.1f}(原模型: 45.2))print(f通用得分:{general_score:.1f}(原模型: 78.5))好的持续预训练领域得分提升 10-30%通用得分下降 ❤️%。持续预训练是给基座模型补知识的重要手段。关键是数据质量跟预训练同分布、学习率小一点、防止遗忘混合通用数据。在昇腾NPU上用 ZeRO-3 做分布式训练8 卡能跑 7B 模型。仓库在这里https://atomgit.com/cann/torch_npu