[ROCm] 官方 AMD Notebook 环境下 BF16 conv-family GPU kernel 覆盖不完整,影响 PaddleOCR-VL 推理
# [ROCm] 官方 AMD Notebook 环境下 BF16 conv-family GPU kernel 覆盖不完整,影响 PaddleOCR-VL 推理
## 环境信息
- 复现时间:2026-04-14 与 2026-04-17
- 平台:`Linux-6.1.0-39-amd64-x86_64-with-glibc2.35`
- Python:`3.12.12`
- ROCm:`7.0.0`
- HIP:`7.0.51831-a3e329ad8`
- 官方 Notebook 中 Paddle wheel 版本:`3.4.0.dev20260123`
- 设备:`gpu:0`
- `paddle.is_compiled_with_rocm() == True`
- `paddle.amp.is_bfloat16_supported() == True`
- `paddle.amp.is_float16_supported() == True`
硬件快照:
- `rocm-smi` 可正常识别 AMD GPU
- `rocminfo` 可正常返回 ROCk 模块信息
## 问题描述
在 AMD GPU + ROCm 的官方 Notebook 环境中,Paddle 在 AMP 层面报告支持 BF16,但 PaddleOCR-VL 视觉推理路径所依赖的关键 conv-family GPU kernel 在运行时并不完整。
这会导致 ROCm 下的 BF16 推理能力不完整,视觉编码器路径无法原生使用 BF16,上层项目只能通过回退到 FP32 或禁用部分 conv 相关 fuse pass 来规避。
## 在官方 Notebook 环境中的最小复现
### 1. `softmax` 的 BF16 可以正常运行
```python
import paddle
import paddle.nn.functional as F
paddle.set_device("gpu:0")
x = paddle.randn([2, 256, 128], dtype="float32").astype("bfloat16")
y = F.softmax(x, axis=-1)
print(y.dtype)
```
该示例在测试环境中可以成功执行。
### 2. `conv2d` 的 BF16 运行失败
```python
import paddle
import paddle.nn.functional as F
paddle.set_device("gpu:0")
x = paddle.randn([1, 3, 64, 64], dtype="float32").astype("bfloat16")
w = paddle.randn([8, 3, 3, 3], dtype="float32").astype("bfloat16")
y = F.conv2d(x, w, padding=1)
```
运行时报错:
```text
(NotFound) The kernel with key (GPU, Undefined(AnyLayout), bfloat16) of kernel `conv2d` is not registered and fail to fallback to CPU one. Selected wrong DataType `bfloat16`. Paddle support following DataTypes: float64, float32.
```
### 3. `conv2d_transpose` 的 BF16 运行失败
```python
import paddle
import paddle.nn.functional as F
paddle.set_device("gpu:0")
x = paddle.randn([1, 8, 32, 32], dtype="float32").astype("bfloat16")
w = paddle.randn([8, 4, 3, 3], dtype="float32").astype("bfloat16")
y = F.conv2d_transpose(x, w, padding=1)
```
运行时报错:
```text
(NotFound) The kernel with key (GPU, Undefined(AnyLayout), bfloat16) of kernel `conv2d_transpose` is not registered and fail to fallback to CPU one. Selected wrong DataType `bfloat16`. Paddle support following DataTypes: float64, float32.
```
### 4. FP16 对照组是正常的
在同一环境中:
- `conv2d(float16)` 可正常执行
- `conv2d_transpose(float16)` 可正常执行
因此这不是 ROCm 下 conv 整体不可用,而是 BF16 覆盖缺口。
## 官方 Notebook wheel 的 runtime kernel registry 证据
通过:
```python
from paddle.base import core
core._get_all_register_op_kernels("phi")
```
检查官方 Notebook 当前 wheel 的运行时 kernel registry,可观察到:
### 缺少 GPU BF16 条目的算子
- `conv2d`
- `conv2d_transpose`
- `conv2d_grad`
- `conv2d_transpose_grad`
- `depthwise_conv2d_transpose`
### 同环境下的正例对照
- `softmax` 存在 GPU BF16 条目,且运行成功
- `depthwise_conv2d` 存在 GPU BF16 条目
这说明问题不是“ROCm 下 BF16 完全不可用”,而是当前 wheel 中 conv-family 相关 GPU BF16 kernel 覆盖不完整,且不同算子之间不一致。
## 影响
这会直接影响 PaddleOCR-VL 在 AMD GPU 上的部署:
- 视觉编码器无法原生使用 BF16
- 上层只能通过 FP32 fallback 规避
- 上层还可能需要禁用 conv 相关 fuse pass
我们已确认 PaddleX 侧目前存在如下 workaround:
- 保持视觉相关模块为 FP32
- 在 ROCm 下删除 `conv2d_add_act_fuse_pass` / `conv2d_add_fuse_pass`
## 关于当前 main 分支源码状态的说明
需要明确区分两件事:
1. 官方 Notebook wheel 暴露的是一个更广的历史运行时缺口
包括 `conv2d` 与 `conv2d_transpose`
2. 当前 `main` 源码状态与官方 Notebook wheel 不完全等同
后续源码核查表明,`conv2d` 的 BF16 source-side support 在 current `main` 中可能已经有更早的上游修复
因此,对应 PR 可能会比本 Issue 的问题范围更窄,只修 current `main` 上剩余的 transpose-conv gap
所以本 Issue 记录的是官方 Notebook 环境中实际观察到的更广运行时问题,而后续 PR 可以只针对 current `main` 上尚未补齐的剩余缺口。
## 期望行为
如果 `paddle.amp.is_bfloat16_supported()` 在 AMD GPU + ROCm 环境下返回 `True`,那么 PaddleOCR-VL 视觉推理路径所需的 conv-family GPU kernel 应具备可用的 BF16 支持。
至少应满足:
- 官方运行时不再需要将视觉 conv 路径强制回退到 FP32
- `conv2d_transpose` 及相关 transpose-conv grad 路径在 current `main` 上应具备 GPU BF16 覆盖
## 建议方向
- 补齐 current `main` 中剩余的 transpose-conv HIP BF16 注册缺口
- 在稳定 ROCm 构建环境中验证 runtime registry 与 BF16 smoke test
- 在文档与 PR 中明确区分:
- 官方 Notebook wheel 的历史运行时现象
- current `main` 对应的剩余源码缺口
## 证据总结
在官方 AMD Notebook runtime 中,已经稳定观察到:
- `paddle.amp.is_bfloat16_supported() == True`
- `paddle.amp.is_float16_supported() == True`
- `softmax(bfloat16)` 在 GPU 上成功
- `conv2d(bfloat16)` 在 GPU 上失败,报 kernel not registered
- `conv2d_transpose(bfloat16)` 在 GPU 上失败,报 kernel not registered
- `conv2d(float16)` 在 GPU 上成功
- `conv2d_transpose(float16)` 在 GPU 上成功
- runtime kernel registry 中:
- `softmax` 有 GPU BF16
- `depthwise_conv2d` 有 GPU BF16
- `conv2d` / `conv2d_transpose` / 对应 grad 没有 GPU BF16
- `fused_conv2d_add_act` 在 runtime 中未注册
2 条评论