当前位置: 首页 > news >正文

探索Qwen2ForCausalLM 架构上进行微调

简述

试验参考了mini_qwen 的开源实现

GitHub - qiufengqijun/mini_qwen: 这是一个从头训练大语言模型的项目,包括预训练、微调和直接偏好优化,模型拥有1B参数,支持中英文。这是一个从头训练大语言模型的项目,包括预训练、微调和直接偏好优化,模型拥有1B参数,支持中英文。. Contribute to qiufengqijun/mini_qwen development by creating an account on GitHub.https://github.com/qiufengqijun/mini_qwen

分词器使用Qwen/Qwen2.5-0.5B-Instruct,通过扩充模型隐藏状态层数、嵌入层维度和注意力头数,增加参数量到1B,使用flash_attention_2进行加速

主要特点:

  • 低资源需求:预训练和微调仅需 12GB 显存,DPO 训练需要 14GB 显存

  • 训练数据:使用来自 BAAI(北京智源人工智能研究院)的数据集,包括用于预训练的 160 亿 tokens、用于微调的 900 万条样本,以及用于偏好优化的 6 万条样本。

数据集

魔塔社区 BAAI/IndustryCorpus2 数据集,根据需要下载


# 下载预训练数据集
modelscope download --dataset 'BAAI/IndustryCorpus2' --include 'film_entertainment/*/high*' --local_dir 'data/pt' # 数据量较大,英文文件选择前3个文件modelscope download --dataset 'BAAI/IndustryCorpus2' --include 'computer_programming_code/*/high*' --local_dir 'data/pt'
modelscope download --dataset 'BAAI/IndustryCorpus2' --include 'computer_communication/*/high*' --local_dir 'data/pt' # 数据量较大,英文文件选择前3个文件modelscope download --dataset 'BAAI/IndustryCorpus2' --include 'tourism_geography/*/high*' --local_dir 'data/pt'
modelscope download --dataset 'BAAI/IndustryCorpus2' --include 'artificial_intelligence_machine_learning/*/high*' --local_dir 'data/pt'
modelscope download --dataset 'BAAI/IndustryCorpus2' --include 'news_media/*/high*' --local_dir 'data/pt'
modelscope download --dataset 'BAAI/IndustryCorpus2' --include 'literature_emotion/*/high*' --local_dir 'data/pt' # 数据量较大,英文文件选择前3个文件modelscope download --dataset 'BAAI/IndustryCorpus2' --include 'accommodation_catering_hotel/*/high*' --local_dir 'data/pt'
modelscope download --dataset 'BAAI/IndustryCorpus2' --include 'current_affairs_government_administration/*/high*' --local_dir 'data/pt' # 数据量较大,英文文件选择前3个文件modelscope download --dataset 'BAAI/IndustryCorpus2' --include 'mathematics_statistics/*/high*' --local_dir 'data/pt'

查看下数据

dataset = load_dataset("parquet", data_files="mini_data/pt/accommodation_catering_hotel/chinese/high/rank_00000.parquet", split="train")
print(dataset[0])

# 大概这么个结构
{"text": "马亮:如何破解外卖骑手的\"生死劫\"\n在消费至上的今天,企业不应道德绑架消费者,让消费者为企业的伪善埋单。。。。。。","alnum_ratio": 0.9146919431,"avg_line_length": 158.25,"char_rep_ratio": 0.044444444400000005,"flagged_words_ratio": 0.0,"max_line_length": 223,"num_words": 404,"perplexity": 858.6,"quality_score": 4.0625,"special_char_ratio": 0.1000526593,"word_rep_ratio": 0.088772846,"_id": 200200005357,"industry_type": "住宿_餐饮_酒店"
}

这个结构是一个经过质量分析或过滤的训练样本的 JSON 表示,用于语言模型训练前的数据评估或筛选阶段。它除了包含原始文本(text)外还包含了一系列用来衡量数据质量的统计特征指标,用于判断该样本是否值得保留用于训练。

🔹 质量指标字段说明:

字段名说明
alnum_ratio字母数字字符所占比例。用于判断文本是否主要为自然语言(而非乱码或表格类数据)
avg_line_length平均每行字符数。可能反映文本结构是否合理(过长/过短)
char_rep_ratio字符重复率。例如“哈哈哈哈哈哈”这种重复率就很高
flagged_words_ratio敏感词或不良词汇占比(0 表示未检测到敏感词)
max_line_length最长一行的字符数。可用于过滤极端异常格式文本
num_words词数总计。用于衡量样本长度
perplexity使用某个语言模型评估的困惑度(perplexity)。数值越低,表示文本越“正常”或模型越容易预测它
quality_score综合质量评分。可能是上述特征加权后的结果,衡量样本是否值得用于训练
special_char_ratio特殊字符(如 #¥%&* 等)在文本中的占比
word_rep_ratio单词重复率(如“外卖外卖外卖平台”)

训练逻辑

加载数据集

# 加载数据集并进行预处理
directories = ["accommodation_catering_hotel","artificial_intelligence_machine_learning","computer_communication","computer_programming_code","film_entertainment","literature_emotion","news_media","tourism_geography","current_affairs_government_administration","mathematics_statistics",
]
data_files = find_files(directories)
dataset = load_dataset("parquet", data_files=data_files, split="train", columns=["text"]) # 只保留text字段
dataset = dataset.shuffle(seed=42)

数据清洗,将原始文本 → 添加结束符 → 分词 → 拼接成一长串 → 按 block_size 切成多个训练用的样本块(每块长度一致),给每条文本加上自定义的“结束符” <|im_end|>,把所有样本的 token 串接在一起(例如把多个 [101,102] 合并为 [101,102,103,104,...]),这是因为 GPT 模型的预训练目标是连续预测序列,所以训练输入是一个“连续的 token 流”。

计算总长度并对齐

  • 得到拼接后 token 总长度(例如 10,356)

  • 只保留整除 block_size(1024)的部分,截断掉尾部多余部分,例如:10356 → 10240(保留完整的 10 块)切成 1024 个 token 一块的样本,每隔 1024 个 token 分一块,生成多个训练样本,输出结构:

{"input_ids": [[token1...token1024], [token1025...token2048], ...],"attention_mask": 同理
}

参考预训练代码

def preprocess_dataset(examples):"""预处理预训练数据集,将文本分词并分块"""eos_token = "<|im_end|>"text_examples = [text + eos_token for text in examples["text"]]  # 添加结束符tokenized_examples = tokenizer(text_examples, add_special_tokens=False)# 将分词结果拼接并分块concatenated_examples = {k: list(chain(*tokenized_examples[k])) for k in tokenized_examples.keys()}total_length = len(concatenated_examples[list(concatenated_examples.keys())[0]])block_size = 1024  # 分块大小total_length = (total_length // block_size) * block_size  # 对齐块大小result = {k: [t[i : i + block_size] for i in range(0, total_length, block_size)]for k, t in concatenated_examples.items()}return result# 应用预处理函数
train_dataset = dataset.map(preprocess_dataset,batched=True,batch_size=5000,remove_columns=dataset.column_names,num_proc=16,
)

,原来有很多条文本,现在经过这段预处理函数:

  • 文本 → 拼接 → 分词 → 连续 token 序列 → 按块切分

  • 输出的每个样本都是 1024 个 token 的一段,可直接送入语言模型进行训练(如 GPT)

数据预处理

训练配置

预训练

accelerate_config.yaml 文件包含了用于配置训练环境的参数。以下是各个配置项的含义:

  • compute_environment: 指定计算环境,这里为本地机器 (LOCAL_MACHINE)。
  • debug: 调试模式,设置为 false 表示不启用调试。
  • deepspeed_config: 包含与 DeepSpeed 相关的配置:
    • gradient_accumulation_steps: 梯度累积步数,这里设置为 16。
    • gradient_clipping: 梯度裁剪值,防止梯度过大,这里为 1.0。
    • offload_optimizer_device: 优化器的卸载设备,这里为 none 表示不卸载。
    • offload_param_device: 参数的卸载设备,这里为 none
    • zero3_init_flag: 是否启用 ZeRO-3 初始化,这里为 false
    • zero_stage: ZeRO 优化的阶段,这里设置为 2。
  • distributed_type: 分布式训练类型,这里为 DEEPSPEED
  • downcast_bf16: 是否降低 bf16 精度,这里设置为 'no'。
  • enable_cpu_affinity: 是否启用 CPU 亲和性,设置为 false
  • machine_rank: 当前机器在分布式训练中的排名,这里为 0。
  • main_training_function: 主训练函数的名称,这里为 main
  • mixed_precision: 混合精度训练,这里使用 bf16。
  • num_machines: 参与训练的机器数量,这里为 1。
  • num_processes: 每台机器上的进程数量,这里为 2。
  • rdzv_backend: rendezvous 后端,这里为 static
  • same_network: 是否在同一网络中,设置为 true
  • tpu_env: TPU 环境配置,这里为空。
  • tpu_use_cluster: 是否使用 TPU 集群,设置为 false
  • tpu_use_sudo: 是否使用 sudo 权限,设置为 false
  • use_cpu: 是否使用 CPU 进行训练,设置为 false

这些配置项帮助用户设置和优化模型训练过程,尤其是在使用 DeepSpeed 进行分布式训练时, 配置参考

compute_environment: LOCAL_MACHINE
debug: false
deepspeed_config:gradient_accumulation_steps: 16gradient_clipping: 1.0offload_optimizer_device: noneoffload_param_device: nonezero3_init_flag: falsezero_stage: 2
distributed_type: DEEPSPEED
downcast_bf16: 'no'
enable_cpu_affinity: false
machine_rank: 0
main_training_function: main
mixed_precision: bf16
num_machines: 1
num_processes: 2
rdzv_backend: static
same_network: true
tpu_env: []
tpu_use_cluster: false
tpu_use_sudo: false
use_cpu: false

训练逻辑

# 已经下载了Qwen2.5-0.5B-Instruct地址
model_path = "./models/Qwen2.5-0.5B-Instruct"
config = AutoConfig.from_pretrained(model_path)# 调整模型配置
config.num_attention_heads = 16
config.num_key_value_heads = 4
config.hidden_size = 1024
config.num_hidden_layers = 48# 加载模型
model = AutoModelForCausalLM.from_config(config, torch_dtype=torch.bfloat16, attn_implementation="flash_attention_2")# 加载分词器
tokenizer = AutoTokenizer.from_pretrained(model_path)# 训练参数配置
training_args = TrainingArguments(output_dir=output_path,overwrite_output_dir=True,learning_rate=1e-4,warmup_ratio=0.1,lr_scheduler_type="cosine",num_train_epochs=1,per_device_train_batch_size=12,gradient_accumulation_steps=16,save_steps=100_000,save_total_limit=3,bf16=True,# save_only_model=True,logging_steps=20,
)# 初始化Trainer
trainer = Trainer(model=model,args=training_args,data_collator=collator,train_dataset=train_dataset,
)

使用accelerate 加速训练

模型参数量: 576851712
表示模型总共有 576,851,712 个参数,也就是约 5.77 亿参数(≈ 577M)。

和之前用的MiniMind架构的模型比训练速度要慢很多,所以直接跳过预训练使用基座进行微调

SFT微调

 trl 配置

# 训练参数配置
training_args = SFTConfig(output_dir=output_path,                 # 训练完成后模型保存的目录overwrite_output_dir=True,             # 如果目录已存在则覆盖原模型learning_rate=1e-5,                    # 学习率,SFT阶段建议小一点warmup_ratio=0.1,                      # 热身步数比例,用于逐渐增加学习率lr_scheduler_type="cosine",            # 学习率调度策略:余弦退火num_train_epochs=3,                    # 训练轮数per_device_train_batch_size=12,        # 每张显卡的batch大小(显存不够就调小)gradient_accumulation_steps=16,        # 梯度累计步数,总batch大小 = 12 × 16 = 192save_strategy="epoch",                 # 每轮结束保存一次模型save_total_limit=3,                    # 最多保存3个checkpoint,旧的自动删掉bf16=True,                             # 使用 bfloat16 进行训练(比 fp16 更稳定,NVIDIA A100/H100 支持)logging_steps=20,                      # 每20步打印一次日志
)# 初始化Trainer
trainer = SFTTrainer(model=model,                           # 使用的模型(已初始化)args=training_args,                    # 上面定义的训练参数train_dataset=dataset,                 # 训练数据集tokenizer=tokenizer,                   # 分词器formatting_func=formatting_prompts_func, # 格式化数据的函数,把样本转换成 prompt + completiondata_collator=collator,               # 数据整理器(例如自动填充、构建input_ids等)
)

相关文章:

  • SAP Business One, Web Client: The Advantages of All Worlds
  • 【Java】Java元注解
  • YOLOv8检测头代码详解(示例展示数据变换过程)
  • 防火墙NAT地址组NAT策略安全策略
  • 香港中农国际集团启动“百校农业计划”,助力全球农业人才培养
  • AI练习:折叠效果
  • 2025 年高尔夫蓝牙音箱市场报告:需求激增下的机遇与挑战
  • 光电耦合器与数字容隔离器的“光速对话”
  • linux cpu占用高的故障怎么排除
  • 智能变电站——三层两网
  • python打卡day34@浙大疏锦行
  • md5升级scram-sha-256认证
  • 文档结构化专家:数字化转型的核心力量
  • 架构师论文《论软件可靠性模型的设计与实现》
  • CAD标注样式如何设置?详细教程来了
  • 解锁内心的冲突:神经症冲突的理解与解决之道
  • 某某观鸟记录(rsa加密、MD5加密)返回数据AES解密逆向分析
  • 回溯算法:解锁多种问题的解决之门
  • 前端可视化
  • 实用蓝牙耳机哪款好?先做好使用场景分析!
  • 做网站有意思吗?/关于搜索引擎的搜索技巧
  • 做一个彩票网站需要怎么做/企业网站建设方案
  • 金山建设机械网站/淘宝网店怎么运营起来
  • 大连网站建设渠道/seo 推广怎么做
  • 模板网站 建设教材/痘痘怎么去除效果好
  • 如何提高网站百度权重/全网热搜榜