接着说后来遇到的新问题:

1.FileNotFoundError: [Errno 2] No such file or directory: './deepseek-llm-7b-chat/pytorch_model-00001-of-00002.bin'

这个错误表明程序在加载模型时,无法找到模型权重文件 pytorch_model-00001-of-00002.bin。这可能是因为模型文件夹路径不正确,或者模型文件没有正确下载或传输。

所以我又用Git重新下载了一遍模型:

huggingface-cli download deepseek-ai/deepseek-llm-7b-chat --local-dir /root/deepseek-llm-7b-chat

(后记:一般第一次下载模型都会不完整,不知道咋回事,所以我每回都会下载同一个模型至少2遍orz)

还要确保代码中的模型路径是正确的:

model_name = "/root/deepseek-llm-7b-chat"

AI建议指定 --repo-type 参数以确保正确下载模型:

huggingface-cli download deepseek-ai/deepseek-llm-7b-chat --local-dir /root/deepseek-llm-7b-chat --repo-type model

这个我倒还没有试过。

2.ValueError: Currently --debug underflow_overflow is not supported under DP. Please use DDP (torchrun or torch.distributed.launch (deprecated)).

这个错误表明我在使用 Trainer 类进行训练时,启用了 underflow_overflow 调试选项:

debug=["datasampler", "dataloader", "underflow_overflow"]

但该选项在数据并行(Data Parallelism, DP)模式下不被支持。Hugging Face 的 Trainer 默认使用 DP 模式进行训练。

解决方法:

不需要调试 underflow_overflow的话,直接移除 TrainingArguments 中的 debug 参数就好了。

# 设置训练参数
training_args = TrainingArguments(
    # 其他参数
    debug=["datasampler", "dataloader"]  # 移除了 "underflow_overflow"
)

但如果需要调试underflow_overflow,就要使用分布式数据并行(DDP)

  • 使用 torchruntorch.distributed.launch 启动训练脚本,而不是直接运行 python文件:

torchrun --nproc_per_node=1 finetune.py
#或者
python -m torch.distributed.launch --nproc_per_node=1 finetune.py

3.AttributeError: 'NoneType' object has no attribute 'backward'

这是因为在训练循环中,outputs.lossNone,导致调用 .backward() 报错。这通常是因为模型的输出格式不匹配,或者没有正确返回损失值。

因此需要确保模型输出包含损失值:

在因果语言模型(Causal Language Model, CLM)中,模型输出的 loss 值通常是基于 labels 字段计算的。确保数据预处理时,labels 字段正确生成。

在预处理步骤,修改 preprocess_function 以包含 labels

def preprocess_function(examples):
    texts = [
        f"### Instruction:\n{instruction}\n### System:\n{system}\n### Response:\n{output}"
        for instruction, system, output in zip(
            examples["instruction"], examples["system"], examples["output"]
        )
    ]
    tokenized_inputs = tokenizer(texts, truncation=True, max_length=1024, padding="max_length")
    tokenized_inputs["labels"] = tokenized_inputs["input_ids"].copy()  # 设置 labels
    return tokenized_inputs

4.TOKENIZERS_PARALLELISM 警告

No label_names provided for model class `PeftModelForCausalLM`. Since `PeftModel` hides base models input arguments, if label_names is not given, label_names can't be set automatically within `Trainer`. Note that empty label_names list will be used instead.

这是一个常见的警告,与 tokenizers 库的并行性设置有关,通常不会影响训练。

在开头添加以下代码,禁用警告就行了:

import os
os.environ["TOKENIZERS_PARALLELISM"] = "false"

5.File "/root/finetune.py", line 116, in training_loop trainer.optimizer.step() AttributeError: 'NoneType' object has no attribute 'step'

这个错误表明 trainer.optimizerNone,因此无法调用 .step() 方法。这通常是因为在自定义训练循环中没有正确初始化优化器。

解决方法:

  1. 使用 Trainer 内置的训练方法:直接调用 trainer.train(),而不是实现自定义训练循环。

  2. 确保优化器被正确初始化:如果需要自定义训练循环,需要手动初始化优化器。

# 自定义训练循环
def training_loop(trainer, train_dataset, eval_dataset):
    optimizer = AdamW(model.parameters(), lr=training_args.learning_rate)  # 手动初始化优化器
    for epoch in range(training_args.num_train_epochs):
        # 训练和评估代码

我需要使用自定义训练循环,所以选择了方法2。

6.`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`.

use_cache=True 是模型的参数(而不是训练参数),用于加速推理过程,但它与训练参数中的梯度检查点(gradient checkpointing)不兼容。

因此,在调用模型时,在模型配置中显式地设置 use_cache=False

# 禁用 use_cache
model.config.use_cache = False

# ……

training_args = TrainingArguments(
    gradient_checkpointing=True, # 梯度检查点
     # 其他参数
)

7.紧接着马上遇到下一个问题:UserWarning: None of the inputs have requires_grad=True. Gradients will be None warnings.warn(

RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn

这个错误表明在梯度计算时,某些张量没有被标记为需要梯度(requires_grad=True),或者没有梯度函数(grad_fn)。这通常发生在以下几种情况:

问题分析:

  1. 模型的某些参数未被正确标记为需要梯度:这通常是因为在模型初始化或数据预处理时,某些张量的 requires_grad 属性被设置为 False。所以,在初始化模型后,要检查所有可训练参数的 requires_grad 属性,确保它们被正确标记为 True

for name, param in model.named_parameters():
    if param.requires_grad:
        print(f"Trainable parameter: {name}")
    else:
        print(f"Parameter {name} does not require grad")
  1. 数据预处理问题labels 字段可能未被正确设置为需要梯度。在数据预处理函数中,确保 labels 字段被正确设置为需要梯度:

def preprocess_function(examples):
    texts = [
        f"### Instruction:\n{instruction}\n### System:\n{system}\n### Response:\n{output}"
        for instruction, system, output in zip(
            examples["instruction"], examples["system"], examples["output"]
        )
    ]
    tokenized_inputs = tokenizer(texts, truncation=True, max_length=1024, padding="max_length")
    tokenized_inputs["labels"] = tokenized_inputs["input_ids"].copy()  # 设置 labels
    tokenized_inputs["labels"] = torch.tensor(tokenized_inputs["labels"], dtype=torch.long)  # 确保 labels 是长整型
    return tokenized_inputs

在初始化模型后,手动检查是否所有可训练参数都被正确标记为需要梯度:

model.train()
for name, param in model.named_parameters():
    if param.requires_grad:
        print(f"Trainable parameter: {name}")
    else:
        print(f"Parameter {name} does not require grad")

这些方法我全叠加使用了,但最有效的还是直接删掉gradient_checkpointing参数。

未完待续……

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐