新手第1次走通LLM本地微调(2)
接着说后来遇到的新问题:这个错误表明程序在加载模型时,无法找到模型权重文件。这可能是因为模型文件夹路径不正确,或者模型文件没有正确下载或传输。(后记:一般第一次下载模型都会不完整,不知道咋回事,所以我每回都会下载同一个模型至少2遍orz)AI建议指定这个我倒还没有试过。这个错误表明我在使用Trainer类进行训练时,启用了但该选项在数据并行(Data Parallelism, DP)模式下不被支持
接着说后来遇到的新问题:
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):
-
使用
torchrun或torch.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.loss 是 None,导致调用 .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.optimizer 是 None,因此无法调用 .step() 方法。这通常是因为在自定义训练循环中没有正确初始化优化器。
解决方法:
-
使用
Trainer内置的训练方法:直接调用trainer.train(),而不是实现自定义训练循环。 -
确保优化器被正确初始化:如果需要自定义训练循环,需要手动初始化优化器。
# 自定义训练循环
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)。这通常发生在以下几种情况:
问题分析:
-
模型的某些参数未被正确标记为需要梯度:这通常是因为在模型初始化或数据预处理时,某些张量的
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")
-
数据预处理问题:
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参数。
未完待续……
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)