You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何记录Python代码执行时Intel GPU的操作以排查Hugging Face Transformers的UR运行时错误

如何记录Python代码执行时Intel GPU的操作以排查Hugging Face Transformers的UR运行时错误

Intel Iris Xe这类集成GPU在Hugging Face Transformers上的支持确实还在逐步完善,遇到这种底层UR指令错误确实挺头疼的。结合你已经排除了 dtype 不兼容的情况,我给你分享几个实用的日志/调试方法,帮你定位到底是哪个操作触发了无效参数错误:

一、用Intel IPEX的底层调试日志抓UR调用细节

你用的是Intel GPU专属的PyTorch wheel(也就是IPEX),它基于SYCL/UR框架实现GPU交互,我们可以通过环境变量开启底层调用日志,直接看到出错的UR指令参数:

在终端运行脚本前,先设置这两个环境变量:

export SYCL_PI_TRACE=2
export IPEX_DEBUG=1

然后再执行你的Python脚本。

这两个变量会打印所有和GPU交互的底层Platform Interface(PI)调用,包括每个UR操作的参数、设备信息。你可以重点看报错前最后几个UR调用,就能精准定位是哪个操作的参数不符合Intel GPU的要求——毕竟UR error 45就是「无效参数」,日志里会把参数细节列得清清楚楚。

二、给PyTorch XPU操作打Hook,追踪Python层张量操作

如果想在Python层面精准追踪所有涉及XPU的张量操作,而不是看底层的SYCL日志,可以用PyTorch的TorchDispatchMode写一个简单的日志Hook:

import torch
from torch.utils._python_dispatch import TorchDispatchMode

class XPULogger(TorchDispatchMode):
    def __torch_dispatch__(self, func, types, args=(), kwargs=None):
        kwargs = kwargs or {}
        # 只记录涉及XPU张量的操作
        has_xpu_tensor = any(
            isinstance(arg, torch.Tensor) and arg.device.type == 'xpu' 
            for arg in args
        ) or any(
            isinstance(v, torch.Tensor) and v.device.type == 'xpu' 
            for v in kwargs.values()
        )
        
        if has_xpu_tensor:
            print(f"\n[XPU OP] 操作名: {func.__name__}")
            print(f"  输入张量详情:")
            for i, arg in enumerate(args):
                if isinstance(arg, torch.Tensor):
                    print(f"    参数{i}: 设备={arg.device},  dtype={arg.dtype}, 形状={arg.shape}")
            for k, v in kwargs.items():
                if isinstance(v, torch.Tensor):
                    print(f"    关键字参数{k}: 设备={v.device},  dtype={v.dtype}, 形状={v.shape}")
        
        # 执行原操作并返回结果
        return func(*args, **kwargs)

# 在你的模型代码前启用这个日志Hook
with XPULogger():
    # 这里放你原有代码:加载模型、处理输入、调用generate
    from transformers import GPT2LMHeadModel, GPT2Tokenizer
    tokenizer = GPT2Tokenizer.from_pretrained('gpt2')
    model = GPT2LMHeadModel.from_pretrained('gpt2').to('xpu:0')
    inputs = tokenizer("Hello, my name is", return_tensors="pt").to('xpu:0')
    sequences = model.generate(**inputs, max_new_tokens=32)

这个Hook会拦截所有PyTorch操作,只打印涉及XPU张量的内容。你可以重点关注出错的那个to()操作(就是attention_mask.to(device=cache_position.device, dtype=torch.bool)),看看cache_position的设备、形状、dtype是不是有异常——比如会不会cache_position意外跑到CPU上了?或者是一个空张量?

三、临时修改Transformers源码,直接打印关键变量

既然你已经知道出错的代码行在transformers/masking_utils.py的723行,最快的方式就是直接在那行前后加日志,打印相关变量的所有细节:

找到你的Transformers安装路径(你的是/home/cemc/.local/lib/python3.10/site-packages/transformers/),打开masking_utils.py,找到_preprocess_mask_arguments函数里的对应行,修改成:

# 临时添加调试日志
print(f"\n[DEBUG] cache_position 详情:")
print(f"  设备: {cache_position.device},  dtype: {cache_position.dtype}, 形状: {cache_position.shape}")
print(f"  是否在XPU上: {cache_position.device.type == 'xpu'}")

print(f"\n[DEBUG] attention_mask 转换前详情:")
print(f"  设备: {attention_mask.device},  dtype: {attention_mask.dtype}, 形状: {attention_mask.shape}")
print(f"  是否在XPU上: {attention_mask.device.type == 'xpu'}")

try:
    attention_mask = attention_mask.to(device=cache_position.device, dtype=torch.bool)
    print(f"\n[DEBUG] attention_mask 转换后详情:")
    print(f"  设备: {attention_mask.device},  dtype: {attention_mask.dtype}")
except Exception as e:
    print(f"\n[DEBUG] 转换时出错: {e}")
    # 抛出错误不中断原有流程
    raise

运行脚本后,你就能看到这两个张量的所有关键状态,一眼就能发现是不是有隐藏的不兼容问题——比如cache_position其实是CPU张量,导致to()操作要跨设备转换时触发了Intel GPU的参数错误。

四、进阶:用Intel VTune Profiler可视化GPU操作流程

如果需要更全面的硬件级分析,可以用Intel官方的VTune Profiler:

  1. 安装VTune:Ubuntu上可以通过Intel oneAPI工具包或者apt直接安装
  2. 创建「GPU Compute」分析任务,选择你的Python脚本作为目标程序
  3. 运行分析后,VTune会生成一个 timeline 视图,展示所有GPU操作的执行顺序,你可以定位到出错的时间点,查看对应的操作参数和硬件状态

这个工具适合复杂的指令不兼容问题,能帮你看到Python层日志看不到的硬件层面细节。

最后给你两个小建议:

  1. 确认IPEX、PyTorch、Transformers的版本兼容性——有时候版本不匹配会导致这种底层指令错误,尽量用IPEX官方推荐的对应版本组合
  2. 可以尝试手动强制把cache_position移到XPU,比如在出错前加一行cache_position = cache_position.to('xpu:0'),或者先把attention_mask转换成XPU张量再做to()操作,说不定能绕过这个参数错误

火山引擎 最新活动