[Model] MiniCPM-o 4.5: enable fused CFM body by default on CUDA (#8557)
Signed-off-by: amy-why-3459 <wuhaiyan17@huawei.com>
This commit is contained in:
1 parent
712b90de9c
commit
9482bf1e8c
3 files changed
+48
-1
No files matched your search
@@ -23,3 +23,14 @@ performance or interruption correctness.
|
||||
The shared asynchronous output snapshot and batched Talker preprocessing also
|
||||
apply to V1 when async chunking/scheduling is enabled. Default V1 behavior must
|
||||
therefore be included in end-to-end regression validation.
|
||||
|
||||
CFM graph execution defaults to the fused DiT body on CUDA when TF32 is
|
||||
allowed. NVIDIA SM80+ uses tiled TF32 attention; older CUDA devices use the
|
||||
fused body's SDPA fallback. Unsupported DiT layouts or non-FP32 attention
|
||||
caches retain the original body. Other platforms retain their existing default.
|
||||
Set `cfm_fused_body: false` in connector `extra` to restore the original body.
|
||||
Disabling TF32 with `token2wav_allow_tf32: false` or
|
||||
`MINICPMO_CODE2WAV_TF32=off` also disables the default fusion choice; an explicit
|
||||
`cfm_fused_body: true` overrides that choice and may use TF32 attention.
|
||||
Slot pooling and row-offset merging remain opt-in. Fusion changes floating-point
|
||||
rounding and does not promise identical waveforms.
|
||||
@@ -172,6 +172,36 @@ def _config(minimum: int = 1, initial: int = 0, *, runtime_prompt_cache_size: in
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("cuda", "extra", "env", "expected"),
|
||||
[
|
||||
(True, {}, None, True),
|
||||
(False, {}, None, False),
|
||||
(True, {"cfm_fused_body": False}, None, False),
|
||||
(True, {"token2wav_allow_tf32": False}, None, False),
|
||||
(True, {"code2wav_allow_tf32": False}, None, False),
|
||||
(True, {}, "off", False),
|
||||
(True, {"token2wav_allow_tf32": False}, "tf32", True),
|
||||
(True, {"cfm_fused_body": True, "token2wav_allow_tf32": False}, None, True),
|
||||
],
|
||||
)
|
||||
def test_cfm_fused_body_default_respects_platform_and_precision(monkeypatch, cuda, extra, env, expected):
|
||||
from vllm_omni.platforms import current_omni_platform
|
||||
|
||||
monkeypatch.setattr(current_omni_platform, "is_cuda", lambda: cuda)
|
||||
monkeypatch.delenv("MINICPMO_CODE2WAV_TF32", raising=False)
|
||||
if env is not None:
|
||||
monkeypatch.setenv("MINICPMO_CODE2WAV_TF32", env)
|
||||
config = _config()
|
||||
config.model_config.stage_connector_config["extra"].update(extra)
|
||||
|
||||
model = MiniCPMO45Code2Wav(vllm_config=config)
|
||||
|
||||
assert model._cfm_graph_config["fused_body"] is expected
|
||||
assert model._cfm_graph_config["slot_pool"] is False
|
||||
assert model._cfm_graph_config["row_offset_merge"] is False
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("extra", "max_num_seqs", "micro"),
|
||||
[
|
||||
|
||||
@@ -288,6 +288,8 @@ class MiniCPMO45Code2Wav(nn.Module):
|
||||
self._runtime_prompt_dir = tempfile.TemporaryDirectory(
|
||||
prefix="minicpmo45-runtime-prompts-",
|
||||
)
|
||||
from vllm_omni.platforms import current_omni_platform
|
||||
|
||||
extra = self._extra_config()
|
||||
self._runtime_prompt_cache_size = int(extra.get("token2wav_runtime_prompt_cache_size", 4))
|
||||
if self._runtime_prompt_cache_size < 0:
|
||||
@@ -342,7 +344,11 @@ class MiniCPMO45Code2Wav(nn.Module):
|
||||
"max_graph_batch": max_graph_batch,
|
||||
"micro_batch_size": micro_batch_size,
|
||||
"pad_max_rows": extra.get("whole_euler_pad_max_rows"),
|
||||
"fused_body": bool(extra.get("cfm_fused_body", False)),
|
||||
# The fused body uses tiled TF32 attention on NVIDIA SM80+;
|
||||
# older CUDA devices retain its SDPA fallback. Respect TF32 opt-out.
|
||||
"fused_body": bool(
|
||||
extra.get("cfm_fused_body", current_omni_platform.is_cuda() and _tf32_mode(extra) != "off")
|
||||
),
|
||||
"slot_pool": bool(extra.get("cfm_slot_pool", False)),
|
||||
"row_offset_merge": extra.get("cfm_row_offset_merge", False) is True,
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user