
故障排除sentence-transformers 训练中的常见失败包含根本原因和修复方法。按症状组织。内存不足OOM症状torch.cuda.OutOfMemoryError或CUDA out of memory。按顺序修复减小per_device_train_batch_size。对 MNRL通过CachedMultipleNegativesRankingLoss(model, mini_batch_size...)配大外部批次来补偿。设置gradient_accumulation_steps以在多个较小的批次上累积梯度用于非对比损失。启用gradient_checkpointingTrue。约慢 30%激活内存减少约 40%。与Cached*损失不兼容。使用bf16True而不是 fp32如果你的 GPU 支持 Ampere。在 transformer 模块上减小max_seq_lengthmodel[0].max_seq_length 128。对大型解码器基座使用 LoRApeft。参见../scripts/train_sentence_transformer_with_lora_example.pydocstring 涵盖何时使用、超参数、QLoRA、陷阱。转到更大的 GPU 或多 GPUaccelerate launch。另见hardware_guide.md中按批次大小的 VRAM 估算。损失为 NaN 或 Inf症状训练损失打印为nan或inf或突然跳到巨大值。修复方法先降低学习率。尝试5e-6或1e-6。启用warmup_steps0.1 1的浮点数被解释为总步数的比例或设置绝对warmup_steps500。从 fp16 切换到 bf16数值上更稳定。如果只能使用 fp16较旧 GPU尝试禁用 fp16 做一次健全性运行。检查数据集中的坏行空字符串、NaN 标签值、列数不匹配。用print(dataset[:5])检查几行。对自定义损失或非常规基座模型非常长的上下文考虑在训练参数中添加max_grad_norm1.0。检查分词某些分词器对特定 unicode / 纯空白输入不产生任何 token这会导致均值池化中的下游 NaN。指标不提升 / 停留在基线症状训练后的评估指标与训练前相同。修复方法用--loss your-loss重新运行数据集检查器。最可能的原因列顺序错误、标签列未被检测到、或损失函数期望不同的形状。对检索你的负样本太容易了。挖掘困难负样本scripts/mine_hard_negatives.py。检查metric_for_best_model——如果键与评估器写入的不匹配训练器会静默使用最终检查点而不是最佳。确认对 MNRL 风格损失设置了BatchSamplers.NO_DUPLICATES。没有它批内负样本信号会被破坏。基座模型对任务不对例如只解码器 LLM 用于短文本 STS。尝试不同的基座。学习率太低。默认2e-5对编码器有效LoRA 需要1e-4静态嵌入需要约2e-1比 transformers 高得多。数据集对所选损失太小。对比损失需要 1 万对才有意义。训练在第一次评估时挂起症状训练开始然后在第一步评估时无限挂起。修复你设置了eval_strategysteps或epoch但要么没有传eval_dataset要么传了一个空的。要么提供eval_dataset要么设置eval_strategyno。训练在启动时挂起多 GPU症状accelerate launch运行打印Found X GPUs 模型加载消息然后挂起。修复方法如果使用自定义数据集类确保实现了__len__并返回跨进程一致的长度。如果使用batch_samplerBatchSamplers.NO_DUPLICATES且数据集相对于全局规模非常小批次可能无法形成。使用更大的数据集或更小的每设备批次。检查节点间 PyTorch / CUDA 版本不匹配。在每个节点上运行nvidia-smipython -c import torch; print(torch.version.cuda)。NCCL 超时。设置NCCL_TIMEOUT300秒环境变量。CachedMultipleNegativesRankingLoss崩溃症状类似element 0 of tensors does not require grad的错误或晦涩的 autograd 错误。修复你启用了gradient_checkpointingTrue。缓存损失自己做前向/反向编排梯度检查点与它冲突。禁用gradient_checkpointing。同样适用于CachedSpladeLoss、CachedGISTEmbedLoss和任何其他Cached*损失。Hub 推送失败症状push_to_hub期间出现HTTPError: 401或403。修复方法运行hf auth whoami。如果失败运行hf auth login。Token 需要写入权限。从 https://huggingface.co/settings/tokens 重新生成。仓库要么必须已存在且你有写权限要么设置了hub_private_repoTrue/False以便库可以创建它。在 HF Jobs 上在作业提交时传secrets{HF_TOKEN: $HF_TOKEN}。TrackerTrackio / WB / TensorBoard未记录症状训练在运行但 tracker UI 中没有指标出现。修复方法Trackio确认pip install trackio成功。无需登录步骤——trackio 使用你的HF_TOKEN由hf auth login或HF_TOKEN环境变量设置。在 HF Jobs 上HF_TOKEN必须在secrets中。WB确认wandb login成功或设置了WANDB_API_KEY环境变量。在 HF Jobs 上WANDB_API_KEY必须在secrets中。report_to未设置为正确的 trackerreport_totrackio或wandb或如[trackio, tensorboard]的列表。TensorBoard检查logging_dir默认为output_dir/runs/timestamp让 TB 指向父目录。基座模型加载但encode产生垃圾症状model.encode([test])返回常量向量、全零或 NaN。修复方法你加载了一个分类微调模型作为基座例如在 SQuAD 上微调的 BERT。CLS 头是 QA 头不是可用的池化层。使用底层预训练编码器bert-base-uncased而不是任务特定检查点。对解码器模型你在因果注意力上使用均值池化。切换到 last-token 池化。对 SPLADE模型的 MLM 头没有正确初始化。确保基座具有AutoModelForMaskedLM兼容性。数据集加载但评估平凡地正确症状从第一次评估步骤起评估指标就是 1.0完美。修复你的评估集与训练集重叠。检查dataset.train_test_split(test_size...)是否正确调用或 Hub 数据集的train与dev拆分是否确实不相交。模型卡生成失败症状关于模型卡生成的警告或save_pretrained后缺少README.md。修复方法codecarbon可能试图写入排放数据并失败。设置CODECARBON_LOG_LEVELerror或卸载 codecarbon。某些训练状态无法序列化带非常规类型的自定义对象。传带有显式字段的model_card_dataSentenceTransformerModelCardData(...)以绕过推断。CrossEncoder 上的num_labels不匹配症状BinaryCrossEntropyLoss抛出关于维度不匹配的错误或CrossEntropyLoss报错。修复num_labels1配BinaryCrossEntropyLossnum_labels2配CrossEntropyLoss。对 BCE 设置CrossEncoder(..., num_labels1)。蒸馏 / listwise / pairwise 训练后 CrossEncoder 评估 nDCG 崩溃症状训练损失看起来健康基线评估看起来正常但训练后评估 nDCG 大幅下降例如 0.59 → 0.14。第一次评估之后的每个检查点都低于基线。根本原因CrossEncoder(num_labels1, ...)上默认的Sigmoid激活函数会把原始 logits 5 饱和为约 1.0。蒸馏/listwise/pairwise 损失MSELoss、MarginMSELoss、LambdaLoss、RankNetLoss、ListNetLoss、ListMLELoss、PListMLELoss、ADRMSELoss在原始 logits 上操作——一旦模型学会把正例推过饱和点排名信息就丢失了。修复用Identity激活构造模型importtorch.nnasnn modelCrossEncoder(...,num_labels1,activation_fnnn.Identity())只对BinaryCrossEntropyLoss保留默认的Sigmoid它内部使用 BCE-with-logits想要可 sigmoid 的输入。LambdaLoss 训练损失很小例如 1e-4训练坏了吗症状使用LambdaLoss(model, weighting_schemeNDCGLoss2PPScheme())和大的K64时训练损失打印在 1e-3 到 1e-5 范围内。根本原因NDCGLoss2PPScheme按折扣加权对的数量归一化该数量大致随 K 扩展。损失的数值大小不是你应跟踪的信号。修复对 LambdaLoss 忽略训练损失改为关注评估指标eval_NanoBEIR_R100_mean_ndcg10或你的metric_for_best_model。如果评估在朝正确方向移动而损失太小这是预期行为。LambdaLoss OOM先降什么症状LambdaLoss训练步骤期间出现CUDA out of memory尤其是在 K64 时。恢复顺序先降低损失上的mini_batch_size。内部前向分块保留了 K 列表语义——这是最便宜的旋钮不会改变实验。降低per_device_train_batch_size并用gradient_accumulation_steps补偿以保持总批次固定。仅作为最后手段降低 K每个查询的候选列表长度。降低 K 会改变损失计算的内容这是实验性更改不是内存调整。对非常大的 K128NDCGLoss2PPScheme会为每个查询物化 O(K²) 权重缓冲区这些不在前向分块覆盖范围内所以即使很小的mini_batch_size也可能不够——此时 K 才是正确的旋钮。加载带自定义内联nn.Module的模型抛出ImportError症状通过train.py训练和保存正常从任何其他脚本predict.py、笔记本或另一个包加载保存的模型失败ImportError: Module __main__ does not define a ClassifierHead attribute根本原因当自定义nn.Module在脚本中内联定义时Python 将其 qualname 记录为__main__.ClassifierHead。ST 在保存时将该 qualname 写入modules.json。从不同的入口点加载无法解析__main__.ClassifierHead——该类在加载器的__main__中不存在。修复方法任一将类移到可导入的模块from my_pkg.heads import ClassifierHead。重新保存使modules.json记录my_pkg.heads.ClassifierHead。使用现成的 ST 模块Dense LayerNorm Dense构建相同形状而不是自定义类——这些始终可加载。注明该模型只能从同一脚本加载对一次性实验可接受不适合交付的模型。SPLADE 嵌入是稠密的不稀疏症状训练后(embedding ! 0).sum(dim-1)是数千而不是约 30-250。修复方法你缺少SpladeLoss包装器。仅SparseMultipleNegativesRankingLoss不会添加 FLOPS 正则化。包装SpladeLoss(model, lossinner_loss, query_regularizer_weight5e-5, document_regularizer_weight3e-5)。正则化器权重太低。增加到 1e-4 或更高。调度器过早归零。SpladeRegularizerWeightSchedulerCallback在训练的前约 33% 将权重从 0 爬到目标值默认warmup_ratio1/3可配置。在非常短的运行上它永远不会达到目标。要么训练更长时间要么设置更高的query_regularizer_weight/document_regularizer_weight来补偿。ValueError: The dataset has ... columns but the loss expects N修复列数不匹配。删除多余的列dataset.remove_columns([...])或用select_columns重新排序。名称无关紧要数量和顺序才重要。CPU 上的编码慢得痛苦症状每秒只有几十个句子而不是数千个。修复方法确保模型在 GPU 上model.to(cuda)或加载时用device_mapauto。对真正的 CPU 推理无 GPU 可用考虑切换到基于StaticEmbedding的模型——在 CPU 上比 transformer 快约 1000 倍。Hub 模型加载但model.encode(prompt_namequery)表现得像没有应用提示词修复保存的模型的config_sentence_transformers.json中没有prompts。训练时在save_pretrained之前设置model.prompts args.prompts或使用SentenceTransformerModelCardData(prompts...)。accelerate launch只在一个 GPU 上运行修复先运行accelerate config设置 GPU 数量和精度。或显式传accelerate launch --multi_gpu --num_processes4 train.py。Cached 损失 PEFT 适配器反向传播失败症状使用带 LoRA 适配器的 Cached* 损失时出现None of the inputs have requires_gradTrue。修复add_adapter之后调用model.transformers_model.enable_input_require_grads()这确保梯度流过冻结基座 可训练适配器。相关参考文档training_args.md共享——影响上述所有内容的参数。hardware_guide.md共享——VRAM 规划和多 GPU。dataset_formats.md共享——列/损失验证。losses_sentence_transformer.md/losses_cross_encoder.md/losses_sparse_encoder.md按模型类型的目录——损失特定怪癖。