|
11 | 11 | import pytest |
12 | 12 | import torch |
13 | 13 | import torch.nn.functional as F |
| 14 | +from executorch.backends.arm.ao_ext import MXFPOpConfig |
14 | 15 | from executorch.backends.arm.test import common |
15 | 16 | from executorch.backends.arm.test.models.Qwen3_VL.qwen3_vl_test_config import ( |
16 | 17 | get_qwen3_vl_2b_instruct_checkpoint_config, |
17 | 18 | ) |
| 19 | +from executorch.backends.arm.test.ops.mxfp.common import MXFPTosaPipelineFP |
18 | 20 | from executorch.backends.arm.test.tester.test_pipeline import ( |
19 | 21 | TosaPipelineFP, |
20 | 22 | VgfPipeline, |
|
25 | 27 | ) |
26 | 28 |
|
27 | 29 | input_t = Tuple[torch.Tensor, ...] |
| 30 | +aten_op_mxfp_linear = "torch.ops.tosa_mxfp.linear.default" |
28 | 31 |
|
29 | 32 |
|
30 | 33 | def _make_qwen3_vl_2b_instruct_layer_config(): |
@@ -104,6 +107,10 @@ def _to_bfloat16_model_and_floating_inputs( |
104 | 107 | ) |
105 | 108 |
|
106 | 109 |
|
| 110 | +def _is_linear(module: torch.nn.Module, _fqn: str) -> bool: |
| 111 | + return isinstance(module, torch.nn.Linear) |
| 112 | + |
| 113 | + |
107 | 114 | class TextModelWrapper(Qwen3VLModelTestModule): |
108 | 115 | def __init__(self, config) -> None: |
109 | 116 | super().__init__() |
@@ -300,3 +307,35 @@ def test_qwen3_vl_full_models_vgf_no_quant_bf16(test_case: Qwen3VLModelTestCase) |
300 | 307 | tosa_spec="TOSA-1.0+FP+bf16", |
301 | 308 | ) |
302 | 309 | pipeline.run() |
| 310 | + |
| 311 | + |
| 312 | +@pytest.mark.slow |
| 313 | +def test_qwen3_vl_text_model_tosa_mxfp8_bf16(): |
| 314 | + # The Qwen 3 VL FP8 model only quantizes the TextModel |
| 315 | + model, inputs = TextModelWrapper.prepare_model_and_inputs() |
| 316 | + model, inputs = _to_bfloat16_model_and_floating_inputs(model, inputs) |
| 317 | + mxfp_config = MXFPOpConfig(weight_dtype=torch.float8_e4m3fn) |
| 318 | + with torch.no_grad(): |
| 319 | + pipeline = MXFPTosaPipelineFP[input_t]( |
| 320 | + model, |
| 321 | + inputs, |
| 322 | + aten_op=aten_op_mxfp_linear, |
| 323 | + exir_op=[], |
| 324 | + filter_fn=_is_linear, |
| 325 | + frobenius_threshold=0.1, |
| 326 | + cosine_threshold=0.98, |
| 327 | + mxfp_config=mxfp_config, |
| 328 | + tosa_version="1.1", |
| 329 | + tosa_extensions=["bf16", "mxfp"], |
| 330 | + ) |
| 331 | + # Check all linear layers are converted to MXFP |
| 332 | + linear_count = sum( |
| 333 | + _is_linear(submodule, name) for name, submodule in model.named_modules() |
| 334 | + ) |
| 335 | + pipeline.add_stage_after( |
| 336 | + "export", |
| 337 | + pipeline.tester.check_count, |
| 338 | + {aten_op_mxfp_linear: linear_count}, |
| 339 | + suffix="mxfp_linear", |
| 340 | + ) |
| 341 | + pipeline.run() |
0 commit comments