RuntimeError: “bernoulli_tensor_cpu_self_” not implemented for ‘Half’`

这个报错通常出现在模型加载时临时把 PyTorch 默认 dtype 改成 fp16,但加载中途抛异常、原 dtype 没有恢复,后续数据处理代码在 fp16 默认 dtype 下生成 CPU 半精度张量并调用 torch.bernoulli 时触发。优先检查 torch.get_default_d

快速结论:这个报错通常出现在模型加载时临时把 PyTorch 默认 dtype 改成 fp16,但加载中途抛异常、原 dtype 没有恢复,后续数据处理代码在 fp16 默认 dtype 下生成 CPU 半精度张量并调用 torch.bernoulli 时触发。优先检查 torch.get_default_dtype() 是否被遗留在 torch.float16。

适用环境:Issue 已确认工具为 Transformers,涉及 PyTorch、from_pretrained 加载流程,以及 DataCollatorForLanguageModeling;Issue 中提到在 Jupyter/Notebook 单元格中运行复现,未提供具体 Python、CUDA、显卡或 PyTorch 版本号。

最快修复方案:升级到 Transformers v4.49.0 或更高版本,该问题已由 PR #35845 修复,在加载抛出异常时通过 finally 恢复默认 dtype。

注意事项:如果暂时无法升级,Issue 中讨论过的方向是使用上下文管理器和/或 finally 来保证恢复原 dtype;但在当前已关闭的讨论链中,没有给出可直接用于旧版本的官方补丁代码,自行修改源码需谨慎。报错本身出现在 torch.bernoulli,但根因通常是默认 dtype 已被污染,不要只针对 bernoulli 打补丁。

问题场景

用户在 Notebook 中加载模型,使用 from_pretrained(..., dtype=torch.float16) 这类半精度加载,并且加载过程中抛出异常。之后继续运行 DataCollatorForLanguageModeling 等数据整理逻辑时,torch.full 生成的 probability_matrix 意外变成 fp16 CPU 张量,随后 torch.bernoulli 拒绝在 CPU Half 张量上执行。

报错原文

RuntimeError: "bernoulli_tensor_cpu_self_" not implemented for 'Half'

原因分析

最可能的原因是:PreTrainedModel._from_config 在加载模型时通过 _set_default_torch_dtype 临时修改 PyTorch 全局默认 dtype,但恢复默认 dtype 的代码不在 finally 中。如果模型构造或加载流程中途抛出异常,恢复逻辑被跳过,torch.get_default_dtype() 会一直停留在 torch.float16。后续代码中不显式指定 dtype 的 torch.full 就会创建 fp16 张量,进而导致 torch.bernoulli 在 CPU 上报不支持 Half。

Issue 评论中确认,from_pretrained 里也有类似调用需要一并处理;维护者倾向使用内部上下文管理器,或在两处用 try/finally 保证恢复。

环境排查

  • 确认 Transformers 版本;Issue 明确修复版本为 v4.49.0,低于该版本可能受影响。
  • 检查当前进程中的 torch.get_default_dtype() 是否为非预期值,例如 torch.float16。
  • 确认是否在 Notebook 中先执行过会抛异常的模型加载单元格,然后未重启内核继续运行数据处理代码。
  • 确认是否使用 from_pretrained(..., dtype=torch.float16) 或等效的默认 dtype 修改路径。
  • 确认报错是否来自 DataCollatorForLanguageModeling 内部的 torch_mask_tokens 和 torch.bernoulli 调用。
  • Issue 未提供 Python、CUDA、PyTorch、显卡版本,排查时以实际环境为准。

解决步骤

  1. 优先尝试升级 Transformers 到 v4.49.0 或更高版本。Issue 末尾明确说明该问题已由 #35845 在 v4.49.0 修复,加载抛出异常时也会恢复默认 dtype。
  2. 升级后重启 Python 进程或 Notebook 内核,避免当前会话中已被污染的全局默认 dtype 继续影响后续运行。
  3. 如果暂时不能升级,可在加载失败后手动执行 torch.set_default_dtype(torch.float32) 恢复默认 dtype,再重试数据处理;这是可优先尝试的会话级规避方法,不是 Issue 中验证过的官方修复。
  4. 如果需要在旧版本中长期修复,可参考 Issue 讨论的方向:为临时设置默认 dtype 增加上下文管理器,确保 __exit__ 中恢复原 dtype;或在 _from_config 和 from_pretrained 的相关调用处使用 try/finally。修改后需要自行验证异常路径。
  5. 排查时避免只捕获 bernoulli 异常,应先确认默认 dtype 状态,否则同类问题仍可能在其他算子或数据类型上出现。

验证方法

在升级或恢复后,先打印 torch.get_default_dtype(),确认加载前后保持为原值,例如 torch.float32。再复现一次“加载时抛异常”的路径,异常被捕获后再次检查默认 dtype 是否已恢复。最后重新运行 DataCollatorForLanguageModeling,确认不再出现 RuntimeError: "bernoulli_tensor_cpu_self_" not implemented for 'Half'。

参考来源

huggingface/transformers #28461

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 29324

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注