多GPU运行Qwen2-VL模型触发CUDA断言错误的解决方法
修复Qwen2-VL多GPU运行时的CUDA设备断言错误
问题场景
拥有4块GPU,运行Qwen2-VL-2B-Instruct模型时触发CUDA设备断言错误,核心报错点为inputs_embeds[image_mask] = image_embeds处索引越界。
使用代码:
model_name="Qwen/Qwen2-VL-2B-Instruct" model = Qwen2VLForConditionalGeneration.from_pretrained( model_name, torch_dtype="auto", device_map="auto" ) model = nn.DataParallel(model) processor = AutoProcessor.from_pretrained(model_name) messages = [ { "role": "user", "content": [ { "type": "image", "image": file }, { "type": "text", "text": """Describe the image""" } ] } ] text = processor.apply_chat_template( messages, tokenize=False, add_generation_prompt=True) image_inputs, video_inputs = process_vision_info(messages) inputs = processor( text=[text], images=image_inputs, videos=video_inputs, padding=True, return_tensors="pt", ) with torch.no_grad(): generated_ids = model.module.generate(**inputs, max_new_tokens=128)
错误详情
../aten/src/ATen/native/cuda/IndexKernel.cu:92: operator(): block: [35,0,0], thread: [31,0,0] Assertion `-sizes[i] <= index && index < sizes[i] && "index out of bounds"` failed. ERROR: CUDA error: device-side assert triggered Compile with `TORCH_USE_CUDA_DSA` to enable device-side assertions. Traceback (most recent call last): File "/home/ubuntu/projects/mistral-qaC/services/VisionService.py", line 104, in ask_vision generated_ids = self.model.module.generate( ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/ubuntu/projects/upper/lib/python3.12/site-packages/torch/utils/_contextlib.py", line 116, in decorate_context return func(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^ File "/home/ubuntu/projects/upper/lib/python3.12/site-packages/transformers/generation/utils.py", line 2015, in generate result = self._sample( ^^^^^^^^^^^^^ File "/home/ubuntu/projects/upper/lib/python3.12/site-packages/transformers/generation/utils.py", line 2965, in _sample outputs = self(**model_inputs, return_dict=True) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/ubuntu/projects/upper/lib/python3.12/site-packages/torch/nn/modules/module.py", line 1553, in _wrapped_call_impl return self._call_impl(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/ubuntu/projects/upper/lib/python3.12/site-packages/torch/nn/modules/module.py", line 1562, in _call_impl return forward_call(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/ubuntu/projects/upper/lib/python3.12/site-packages/accelerate/hooks.py", line 169, in new_forward output = module._old_forward(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/ubuntu/projects/upper/lib/python3.12/site-packages/transformers/models/qwen2_vl/modeling_qwen2_vl.py", line 1598, in forward inputs_embeds[image_mask] = image_embeds ~~~~~~~~~~~~~^^^^^^^^^^^^ RuntimeError: CUDA error: device-side assert triggered Compile with `TORCH_USE_CUDA_DSA` to enable device-side assertions.
已尝试方案
- 使用
CUDA_LAUNCH_BLOCKING=1 python script.py运行脚本,无效 - 确认模型和输入设备均为
cuda:0 - 生成前执行
torch.cuda.synchronize()和torch.cuda.empty_cache()
输入张量形状
- input_ids: torch.Size([1, 759])
- attention_mask: torch.Size([1, 759])
- pixel_values: torch.Size([2940, 1176])
- image_grid_thw: torch.Size([1, 3])
环境版本
transformers==4.45.0.dev0 torch==2.4.1+cu124
解决方法
1. 移除nn.DataParallel包装
transformers库的from_pretrained配合device_map="auto"已经自动实现多GPU模型分配,额外套nn.DataParallel会导致模型张量拆分逻辑冲突,引发索引越界。修改代码如下:
model_name="Qwen/Qwen2-VL-2B-Instruct" model = Qwen2VLForConditionalGeneration.from_pretrained( model_name, torch_dtype="auto", device_map="auto" ) # 移除该行:model = nn.DataParallel(model) processor = AutoProcessor.from_pretrained(model_name) # ... 其余代码不变 ... with torch.no_grad(): # 直接调用model.generate,无需使用model.module.generate generated_ids = model.generate(**inputs, max_new_tokens=128)
2. 修正图像输入处理逻辑
自定义的process_vision_info函数可能返回格式错误的图像输入,导致pixel_values形状异常(当前缺少batch维度)。改为直接从messages中提取图像:
# 替换原有的image_inputs, video_inputs = process_vision_info(messages) image_inputs = [] for msg in messages: for content_item in msg["content"]: if content_item["type"] == "image": image_inputs.append(content_item["image"]) video_inputs = [] # 无视频输入时设为空列表
3. 确保输入张量与模型设备对齐
将处理后的输入张量移至模型所在设备:
inputs = processor( text=[text], images=image_inputs, videos=video_inputs, padding=True, return_tensors="pt", ) # 添加该行代码 inputs = {k: v.to(model.device) for k, v in inputs.items()}
4. 验证pixel_values形状
处理后的pixel_values应符合模型要求的格式(通常为[batch_size, channels, height, width]),若仍异常,需检查图像输入是否为PIL.Image或numpy数组格式,避免传入扁平化的张量。
内容的提问来源于stack exchange,提问作者Cihan Yalçın
相关产品推荐
相关产品推荐

