Windows下使用transformers加载预训练TF-BERT模型时Python进程崩溃问题
问题根因说明
你遇到的退出码0xC0000005是Windows系统特有的内存访问违规错误,结合日志停在cuBLAS库加载完成的节点、仅在transformers调用TF模型的from_pretrained方法时触发的特征,这是Windows平台上TF框架与transformers库的已知兼容问题,并非个人配置错误,大量使用Windows环境开发的开发者都遇到过同类问题。
这也解释了为什么你单独运行TensorFlow、PyTorch时没有异常:两个框架单独运行时,CUDA相关dll只会被加载初始化一次,不会出现重复调用的情况。这类问题的核心触发逻辑是:Windows的动态库加载机制和Linux不同,不会自动去重已经加载到进程内存的CUDA系列dll,当transformers在加载TF模型权重时,会重复触发cuBLAS/cuDNN库的初始化流程,直接触发内存越界访问,导致程序崩溃。
可落地的解决方法
- 方案1:固定适配稳定的TensorFlow版本
不要使用2.4及以上的GPU版TensorFlow,直接安装经过验证的稳定版本2.3.4,该版本在Windows平台对cuBLAS 11、cuDNN 8的适配最完善,不会和transformers的TF模型加载逻辑冲突,可直接用命令安装:
该版本可和现有GPU版PyTorch共存,无需卸载已安装的PyTorch环境。pip install tensorflow==2.3.4 - 方案2:调整GPU内存分配逻辑规避冲突
如果必须使用新版TensorFlow,需要在所有import tensorflow、import transformers的语句之前,先加上环境变量配置,替换TF默认的内存分配器:
同时调用import os # 开启异步显存分配,避免重复申请显存触发访问违规 os.environ["TF_GPU_ALLOCATOR"] = "cuda_malloc_async" os.environ["CUDA_VISIBLE_DEVICES"] = "0"from_pretrained方法时,强制跳过PyTorch权重到TF张量的转换流程,避免GPU上的张量搬运触发dll冲突:
注意需要提前将对应模型的TF格式权重文件缓存到本地,避免transformers自动下载PyTorch格式权重做在线转换。model = TFBertForSequenceClassification.from_pretrained( 'bert-base-uncased', from_pt=False, ) - 方案3:升级适配的NVIDIA驱动
GTX 1060(计算能力6.1)刚好处于cuBLAS 11的Windows驱动适配边界,R460及更早版本的NVIDIA驱动在调用cublasLt64_11.dll时会随机触发内存访问错误,将驱动升级到R470.xx以上的稳定版可大幅降低崩溃概率,不建议使用最新的测试版驱动。 - 临时兜底方案
如果上述调整暂时无法落地,可先在脚本最开头设置强制使用CPU加载模型,待模型权重加载完成后再手动将权重搬运到GPU显存,该方式可100%避开dll加载冲突:import os os.environ["CUDA_VISIBLE_DEVICES"] = "-1" # 执行模型加载流程 ... # 加载完成后恢复GPU可见性,将模型搬运到显存 os.environ["CUDA_VISIBLE_DEVICES"] = "0"
注意:Linux平台不存在这类问题,因为Linux的动态链接器会自动去重进程内已经加载的共享库,不会出现重复初始化导致的内存越界。
内容的提问来源于stack exchange,提问作者Claudio Mazzoni
相关产品推荐
相关产品推荐

