
cuda: reset cuda context (#23935) causes multi-GPU split buffer crash during model load
快速结论:该报错发生在多 GPU 场景下使用 -sm row 拆分策略加载大模型时,主要原因是 commit 0f7fada56 引入的 cudaDeviceReset() 在多设备查询显存时误销毁 CUDA 上下文。优先排查是否使用了包含 PR #23935 或 commit 0f7fada56 的构建版本,并尝试回退或升级到修复版本。
问题场景
用户使用 3× RTX 3090 运行 llama.cpp(commit 2490fe65b 至 0f7fada56 之间版本),以 -sm row 模式加载 Gemma4-31B Q6_K_L 模型。在模型权重加载过程中发生崩溃。此前同一配置在更早提交下可正常加载。
报错原文
ggml_backend_cuda_split_buffer_set_tensor
llama_model_loader::load_all_data
llama_model_base::load_tensors
llama_model_load
原因分析
PR #23935 在 ggml_backend_cuda_device_get_memory() 函数中,当 active_count == 0 时调用 cudaDeviceReset()。在多 GPU 模型加载序列中,系统会依次查询每个设备的可用显存以确定张量放置。如果在某个设备的查询时刻 active_count 为零(可能发生在加载过程中缓冲区分配的间隙),cudaDeviceReset() 会销毁该设备的 CUDA 上下文。后续向该设备复制模型权重时,ggml_backend_cuda_split_buffer_set_tensor 因 CUDA 上下文丢失而失败。
单 GPU 配置几乎不会触发此问题,因为显存查询和缓冲区分配的交织方式不同。
环境排查
- 操作系统:Linux (Ubuntu 24.04)
- 硬件:3× RTX 3090 (Ampere, SM 8.6)
- CUDA 版本:12.x
- 影响版本:包含 commit 0f7fada56(即 PR #23935)的构建版本(例如 b9586–b9716 区间)
- 修复版本:PR #24715(回退了 #23935),合并于 2026-06-17,对应 commit b9861
解决步骤
- 确认当前 llama.cpp 构建版本(运行
llama-server --version或查看 git log)。 - 如果版本位于受影响区间(包含 commit 0f7fada56),请将代码升级到 PR #24715 合并后的版本(如 commit b9861 或更新)。
可优先尝试:从 master 分支拉取最新代码并重新编译。 - 如果暂时无法升级,考虑使用
-sm tensor替换-sm row测试是否可规避(仅作为临时方案,Issue 中未充分验证)。 - 注意:在修复版本中,使用量化 KV 缓存(
-ctk q4_0 -ctv q8_0)配合-sm row可能导致生成速度严重下降(5.3 t/s)。若遇到此问题,建议改用 f16 KV 缓存以获得可接受性能。
验证方法
使用修复后的版本,以相同的命令(包括 -sm row 和模型路径)重新加载 Gemma4-31B Q6_K_L,确认模型权重加载过程不再崩溃。可进一步验证生成速度是否正常(例如使用 f16 KV 缓存应得到 28.5 t/s 左右的表现)。



