解决 RuntimeError: “LayerNormKernelImpl” not implemented for ‘Half’。
错误类似如下:
Traceback (most recent call last):
File “cli_demo.py”, line 21, in
for results in webglm.stream_query(question):
File “/root/WebGLM/model/modeling_webglm.py”, line 49, in stream_query
outputs = self.model.generate(**inputs, max_length=1024, eos_token_id = self.tokenizer.eop_token_id, pad_token_id=self.tokenizer.eop_token_id)
File “/usr/local/python3/lib/python3.8/site-packages/torch/autograd/grad_mode.py”, line 27, in decorate_context
return func(*args, **kwargs)
File “/usr/local/python3/lib/python3.8/site-packages/transformers/generation/utils.py”, line 1515, in generate
return self.greedy_search(
File “/usr/local/python3/lib/python3.8/site-packages/transformers/generation/utils.py”, line 2332, in greedy_search
outputs = self(
File “/usr/local/python3/lib/python3.8/site-packages/torch/nn/modules/module.py”, line 1130, in _call_impl
return forward_call(*input, **kwargs)
File “/root/.cache/huggingface/modules/transformers_modules/WebGLM-2B/modeling_glm.py”, line 902, in forward
model_output = self.glm(input_ids, position_ids, attention_mask, mems=mems, **kwargs)
File “/usr/local/python3/lib/python3.8/site-packages/torch/nn/modules/module.py”, line 1130, in _call_impl
return forward_call(*input, **kwargs)
File “/root/.cache/huggingface/modules/transformers_modules/WebGLM-2B/modeling_glm.py”, line 783, in forward
transformer_output = self.transformer(embeddings, position_ids, attention_mask, mems)
File “/usr/local/python3/lib/python3.8/site-packages/torch/nn/modules/module.py”, line 1130, in _call_impl
return forward_call(*input, **kwargs)
File “/root/.cache/huggingface/modules/transformers_modules/WebGLM-2B/modeling_glm.py”, line 595, in forward
hidden_states = layer(*args, mem=mem_i)
File “/usr/local/python3/lib/python3.8/site-packages/torch/nn/modules/module.py”, line 1130, in _call_impl
return forward_call(*input, **kwargs)
File “/root/.cache/huggingface/modules/transformers_modules/WebGLM-2B/modeling_glm.py”, line 417, in forward
layernorm_output = self.input_layernorm(hidden_states)
File “/usr/local/python3/lib/python3.8/site-packages/torch/nn/modules/module.py”, line 1130, in _call_impl
return forward_call(*input, **kwargs)
File “/usr/local/python3/lib/python3.8/site-packages/torch/nn/modules/normalization.py”, line 189, in forward
return F.layer_norm(
File “/usr/local/python3/lib/python3.8/site-packages/torch/nn/functional.py”, line 2503, in layer_norm
return torch.layer_norm(input, normalized_shape, weight, bias, eps, torch.backends.cudnn.enabled)
RuntimeError: “LayerNormKernelImpl” not implemented for ‘Half’
在深度学习中,Layer Normalization(层标准化)是一种常用的技术,用于加速训练和提高模型稳定性。然而,在某些情况下,您可能会遇到RuntimeError: “LayerNormKernelImpl“ not implemented for ‘Half‘错误。这个错误通常意味着在半精度(即float16)模式下,Layer Normalization的实现存在问题。
问题原因:
硬件和软件不兼容:某些深度学习框架(如PyTorch)在某些硬件上可能不支持半精度Layer Normalization。
模型和层配置问题:在模型定义或配置中,可能存在与半精度不兼容的设置。
版本问题:使用的深度学习框架或库的版本可能存在已知的bug或不兼容性。
解决方案:
检查硬件和软件支持:确保您的硬件和软件支持半精度运算。某些GPU可能不完全支持半精度运算,此时可以考虑使用其他GPU或升级驱动程序和框架版本。
使用全精度运算:作为一种临时解决方案,您可以尝试将模型和训练切换到全精度(即float32)模式。这可以通过修改模型配置或设置训练参数来实现。
更新框架和库:检查是否有可用的更新,并确保您使用的是最新版本的深度学习框架和相关库。新版本可能修复了与半精度运算相关的问题。
自定义实现:如果框架本身不支持半精度Layer Normalization,您可以考虑自己实现该层。这需要一定的深度学习和编程知识,但可以提供更大的灵活性和控制力。
查找相关社区和论坛:参与相关的开发者社区和论坛,查找类似问题的解决方案和讨论。这些社区通常由经验丰富的开发者组成,可以提供宝贵的建议和解决方案。
预防措施:
文档阅读:在开始项目之前,仔细阅读您所使用的深度学习框架的文档。了解半精度运算的支持情况和最佳实践。
测试不同设置:在进行模型训练之前,尝试在不同的设置(如不同的硬件、软件版本等)下进行测试,以识别潜在的问题区域。
持续关注更新:保持对深度学习框架和相关库的关注,以便及时了解任何与半精度运算相关的改进和新特性。
代码审查:定期进行代码审查,确保代码中没有与半精度运算不兼容的配置或设置。
备份和记录:在进行任何更改之前,始终备份您的项目代码和配置。这样,如果出现问题,您可以轻松回滚到之前的状态并进行调试。
解决方法:
export COMMANDLINE_ARGS="--use-cpu all --precision full --no-half --skip-torch-cuda-test"
export COMMANDLINE_ARGS="--skip-torch-cuda-test --precision full --no-half"
export COMMANDLINE_ARGS="--skip-torch-cuda-test --no-half --use-cpu all"
export COMMANDLINE_ARGS="--skip-torch-cuda-test --upcast-sampling --no-half-vae --use-cpu interrogate --precision full --no-half"
export COMMANDLINE_ARGS="--autolaunch --skip-torch-cuda-test --disable-nan-check --no-half --use-cpu all"
-–skip-torch-cuda-test:这个参数是用来跳过检测 torch 是否能使用 GPU 的,如果您的 CUDA 和 torch 版本不匹配,或者您的电脑没有 CUDA GPU ,可以使用这个参数来绕过这个检测。
-–precision full:这个参数是用来指定 torch使用全精度(32位)的浮点数来运算的,相比于半精度(16位)或混合精度(16位和32位),全精度可以提高运算的准确性,但也会增加运算的时间和内存消耗。
-–no-half:这个参数是用来禁止 torch 使用半精度的数据类型的,如果您的显卡不支持半精度,或者您遇到了 “LayerNormKernelImpl” not implemented for ‘Half’ 的错误,可以使用这个参数来解决。
如果还是不行,可以考虑修改代码解决:
这个错误通常发生在尝试以半精度(Half)模式运行包含层归一化(Layer Norm)操作的代码时。具体来说,该错误表示图形处理器(GPU)上不支持半精度数据的层归一化操作。
要解决这个问题,可以尝试以下方法:
-
确保你使用的是最新版本的 PyTorch。更新到最新版本可能会修复此问题。你可以使用以下命令检查和更新 PyTorch:
pip install --upgrade torch
-
在运行层归一化操作之前,将数据类型转换为全精度(Float)模式:
# 将输入数据转换为全精度(Float)类型 inputs = inputs.float() # 执行模型操作 outputs = self.model.generate(**inputs, max_length=1024, eos_token_id=self.tokenizer.eop_token_id, pad_token_id=self.tokenizer.eop_token_id) # 如果需要,将数据类型转回半精度(Half) inputs = inputs.half()
-
如果你的系统支持,可以尝试禁用 GPU 加速,将代码切换到 CPU 运行:
# 在初始化模型之前禁用 GPU 加速 torch.backends.cudnn.enabled = False # 初始化模型和其他相关操作 # ... # 执行模型操作 # ...
例如:
Benchmark模式会提升计算速度,但是由于计算中有随机性,每次网络前馈结果略有差异。如果想要避免这种结果波动,设置:
torch.backends.cudnn.deterministic = True
设置为True,说明设置为使用使用非确定性算法:
torch.backends.cudnn.enabled = True
整体使用:
在模型的开始之前添加:
import torch.backends.cudnn as cudnn
cudnn.deterministic = True
cudnn.benchmark = True
cudnn.enabled = True
CPU运行的报错似乎与pytorch有关,CPU推理目前仍只支持fp32。
最后如果代码里面 模型 初始化的时候,调用了半精度,例如:
self.model = self.model.half()
修改为:
if device != "cpu":
self.model = self.model.half()