步骤&代码解析~

1. 导入库

import torch
from transformers import (
    Qwen2VLForConditionalGeneration,
    AutoTokenizer,
    AutoModelForCausalLM,
    Trainer,
    TrainingArguments,
    DataCollatorForLanguageModeling
)
from datasets import Dataset
from peft import LoraConfig, get_peft_model
import os
  • import torch:导入 PyTorch,用于张量操作和模型训练。

  • from transformers import ...

    • Qwen2VLForConditionalGeneration:Qwen2VL 模型的生成类,支持视觉和语言,这里仅用文本部分。

    • AutoTokenizer:自动加载对应模型的 tokenizer。

    • AutoModelForCausalLM:用于因果语言模型的基类(此处未直接使用,但保留)。

    • Trainer:Hugging Face 的训练器,简化训练循环。

    • TrainingArguments:配置训练超参数。

    • DataCollatorForLanguageModeling:数据整理器,用于语言模型(MLM=False 表示 CLM)。

  • from datasets import Dataset:加载 Hugging Face 的 Dataset 库,方便处理数据。

  • from peft import LoraConfig, get_peft_model:用于 LoRA 微调,配置 LoRA 参数并将模型转换为 LoRA 模型。

  • import os:操作系统接口,可能用于路径操作(但后续未使用)。


2. 配置参数

MODEL_NAME = "./Qwen/qwen2vl7Binstruct/" # 修改为你的文件夹路径
DATA_PATH = "./cleaned_text.txt"
SEQ_LENGTH = 1024                # 根据中文文本长度优化
LORA_RANK = 8
  • MODEL_NAME:预训练模型的本地路径(应是包含 config.json 等文件的目录)。

  • DATA_PATH:训练数据文本文件路径,假设是清洗后的中文文本。

  • SEQ_LENGTH:每个输入序列的最大长度(token 数),此处设为 1024。

  • LORA_RANK:LoRA 低秩矩阵的秩,控制参数量。


3. 加载模型与分词器

tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True)
  • 使用 AutoTokenizer 从指定路径加载 tokenizer,trust_remote_code=True 允许执行自定义代码(Qwen 模型需要)。

model = Qwen2VLForConditionalGeneration.from_pretrained(
    MODEL_NAME,
    trust_remote_code=True,
    torch_dtype=torch.bfloat16,
    device_map="auto"
)
  • 加载 Qwen2VL 模型:

    • torch_dtype=torch.bfloat16:使用 bfloat16 精度以节省显存。

    • device_map="auto":自动将模型层分配到可用设备(如 GPU/CPU)。

# 冻结视觉模块
for name, param in model.named_parameters():
    if "vision" in name or "cross_attention" in name:
        param.requires_grad = False
  • 遍历模型所有参数,如果参数名称包含 "vision" 或 "cross_attention",则冻结(不计算梯度)。这是因为我们只微调文本部分,视觉模块保持预训练权重不变。

# LoRA配置
peft_config = LoraConfig(
    r=LORA_RANK,
    lora_alpha=32,
    target_modules=["q_proj", "v_proj"],
    lora_dropout=0.05,  # 中文数据适当降低dropout
    bias="none",
    task_type="CAUSAL_LM"
)
  • 配置 LoRA:

    • r=LORA_RANK:秩为 8。

    • lora_alpha=32:缩放因子,通常为 2*r 经验值。

    • target_modules=["q_proj", "v_proj"]:在注意力层的 Q 和 V 投影上应用 LoRA。

    • lora_dropout=0.05:LoRA 层的 dropout,注释说中文数据适当降低。

    • bias="none":不训练偏置。

    • task_type="CAUSAL_LM":任务类型为因果语言模型。

model = get_peft_model(model, peft_config)
  • 将原模型包装为 PEFT 模型(添加 LoRA 适配器),返回的模型只训练 LoRA 参数。


4. 数据处理(适配已分块文本)

def load_preprocessed_data(file_path):
    # 假设每个段落已经是分块好的文本块
    with open(file_path, 'r', encoding='utf-8') as f:
        # 按两个换行符分割段落(根据实际数据格式调整)
        text_blocks = f.read().split('\n')  
  • 定义函数读取文件,按换行符 \n 分割(注释说可能按两个换行符,但代码实际是按单个换行分割)。

  • 注意:分割结果可能包含空行。

   # 过滤空行并添加续写提示
    processed_blocks = []
    for block in text_blocks:
        if len(block.strip()) > 10:  # 过滤短于10字符的段落
            processed_blocks.append(block.strip() + "\n")  # 添加续写提示
    print("processed_blocks长度:",len(processed_blocks))
  • 遍历每个块,去除首尾空格后如果长度 >10,则添加换行符(作为续写提示,即让模型学习在文本后生成后续内容)。

  • 打印处理后的块数量。

  return {"text": processed_blocks}
  • 返回字典,键 "text" 对应文本列表。

# 创建数据集
dataset = Dataset.from_dict(load_preprocessed_data(DATA_PATH))
  • 使用 Dataset.from_dict 将返回的字典转换为 Hugging Face Dataset 对象。

# 分词处理(禁用自动分块)
def tokenize_function(examples):
    return tokenizer(
        examples["text"],
        truncation=True,
        max_length=SEQ_LENGTH,
        padding='max_length',  # 固定长度填充
        return_tensors="pt"
    )
  • 定义分词函数:

    • examples["text"]:一批文本。

    • truncation=True:如果文本超长则截断到 max_length

    • max_length=SEQ_LENGTH:最大长度 1024。

    • padding='max_length':填充到固定长度(所有样本长度统一为 1024)。

    • return_tensors="pt":返回 PyTorch 张量。

dataset = dataset.map(
    tokenize_function,
    batched=True,
    remove_columns=["text"],
    batch_size=100  # 提升处理效率
)
  • 对数据集应用分词函数:

    • batched=True:批量处理。

    • remove_columns=["text"]:移除原始文本列,保留 tokenized 后的列(如 input_idsattention_mask)。

    • batch_size=100:每次处理 100 个样本。


5. 训练配置优化

training_args = TrainingArguments(
    output_dir="./cizhouyao-output",
    per_device_train_batch_size=1,      # 因文本长度缩短可增大batch
    gradient_accumulation_steps=1,
    learning_rate=2e-5,                # 中文数据适当提高学习率
    num_train_epochs=1,
    logging_steps=20,
    save_strategy="steps",
    save_steps=200,
    save_total_limit=2,
    fp16=True,
    report_to="tensorboard",
    eval_strategy="no",
    weight_decay=0.01,                 # 防止中文过拟合
    warmup_ratio=0.1                   # 中文训练需要更多warmup
)
  • 配置训练参数:

    • output_dir:模型保存路径。

    • per_device_train_batch_size=1:每个设备上的 batch size(因显存限制设为 1)。

    • gradient_accumulation_steps=1:梯度累积步数。

    • learning_rate=2e-5:学习率。

    • num_train_epochs=1:训练 1 个 epoch。

    • logging_steps=20:每 20 步打印日志。

    • save_strategy="steps":按步数保存模型。

    • save_steps=200:每 200 步保存一次。

    • save_total_limit=2:最多保留 2 个检查点。

    • fp16=True:启用混合精度训练(16 位浮点)。

    • report_to="tensorboard":日志发送到 TensorBoard。

    • eval_strategy="no":不进行评估。

    • weight_decay=0.01:权重衰减系数。

    • warmup_ratio=0.1:学习率 warmup 比例。

data_collator = DataCollatorForLanguageModeling(
    tokenizer=tokenizer,
    mlm=False
)
  • 创建数据整理器:

    • mlm=False:表示不进行掩码语言建模,而是用于因果语言建模(CLM),即自动构建 labels 为 input_ids(标准 CLM 设置)。


6. 开始训练

trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=dataset,
    data_collator=data_collator
)
  • 实例化 Trainer:

    • model:LoRA 微调后的模型。

    • args:训练参数。

    • train_dataset:训练数据集。

    • data_collator:数据整理器。

trainer.train()
  • 启动训练。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐