Skip to content

Commit 11a411d

Browse files
author
Guang Yang
committed
Cover custom sdpa + kv cache + quant in CI
1 parent de493ba commit 11a411d

4 files changed

Lines changed: 125 additions & 18 deletions

File tree

tests/models/test_modeling_llama.py

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import logging
1818
import os
1919
import subprocess
20-
import sys
2120
import tempfile
2221
import unittest
2322

@@ -33,9 +32,6 @@
3332
from ..utils import check_causal_lm_output_quality
3433

3534

36-
is_linux_ci = sys.platform.startswith("linux") and os.environ.get("GITHUB_ACTIONS") == "true"
37-
38-
3935
@pytest.mark.skipif(
4036
parse(torchao.__version__) < parse("0.11.0.dev0"),
4137
reason="Only available on torchao >= 0.11.0.dev0",
@@ -57,10 +53,11 @@ def test_llama3_2_1b_export_to_executorch(self):
5753
--model {model_id} \
5854
--task {task} \
5955
--recipe {recipe} \
60-
--output_dir {tempdir}/executorch \
6156
--use_custom_sdpa \
57+
--use_custom_kv_cache \
6258
--qlinear \
63-
--qembedding",
59+
--qembedding \
60+
--output_dir {tempdir}/executorch",
6461
shell=True,
6562
check=True,
6663
)
@@ -74,15 +71,18 @@ def test_llama3_2_1b_export_to_executorch(self):
7471

7572
@slow
7673
@pytest.mark.run_slow
77-
@pytest.mark.skipif(is_linux_ci, reason="OOM on linux runner")
78-
def test_llama3_2_1b_text_generation(self):
79-
# TODO: Switch to use meta-llama/Llama-3.2-1B once https://github.com/huggingface/optimum/issues/2127 is fixed
80-
# model_id = "lama/Llama-3.2-1B"
74+
def test_llama_text_generation_with_custom_sdpa_8da4w_8we(self):
75+
# ExecuTorch model + custom sdpa + 8da4w linear quantization + int8 embedding quantization
8176
model_id = "NousResearch/Llama-3.2-1B"
82-
model = ExecuTorchModelForCausalLM.from_pretrained(model_id, recipe="xnnpack")
77+
kwargs = {"qlinear": True, "qembedding": True}
78+
model = ExecuTorchModelForCausalLM.from_pretrained(
79+
model_id,
80+
recipe="xnnpack",
81+
attn_implementation="custom_sdpa",
82+
**kwargs,
83+
)
8384
self.assertIsInstance(model, ExecuTorchModelForCausalLM)
8485
self.assertIsInstance(model.model, ExecuTorchModule)
85-
8686
tokenizer = AutoTokenizer.from_pretrained(model_id)
8787
generated_text = model.text_generation(
8888
tokenizer=tokenizer,
@@ -101,19 +101,18 @@ def test_llama3_2_1b_text_generation(self):
101101

102102
@slow
103103
@pytest.mark.run_slow
104-
def test_llama_text_generation_with_custom_sdpa_8da4w_8we(self):
105-
# ExecuTorch model + custom sdpa + 8da4w linear quantization + int8 embedding quantization
104+
def test_llama_text_generation_with_custom_sdpa_and_kv_cache_8da4w_8we(self):
106105
model_id = "NousResearch/Llama-3.2-1B"
107-
kwargs = {"qlinear": True, "qembedding": True}
106+
tokenizer = AutoTokenizer.from_pretrained(model_id)
108107
model = ExecuTorchModelForCausalLM.from_pretrained(
109108
model_id,
110109
recipe="xnnpack",
111110
attn_implementation="custom_sdpa",
112-
**kwargs,
111+
use_custom_kv_cache=True,
112+
**{"qlinear": True, "qembeeding": True},
113113
)
114114
self.assertIsInstance(model, ExecuTorchModelForCausalLM)
115115
self.assertIsInstance(model.model, ExecuTorchModule)
116-
tokenizer = AutoTokenizer.from_pretrained(model_id)
117116
generated_text = model.text_generation(
118117
tokenizer=tokenizer,
119118
prompt="Simply put, the theory of relativity states that",

tests/models/test_modeling_olmo.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,3 +119,32 @@ def test_olmo_text_generation_with_custom_sdpa_8da4w_8we(self):
119119
gc.collect()
120120

121121
self.assertTrue(check_causal_lm_output_quality(model_id, generated_tokens))
122+
123+
@slow
124+
@pytest.mark.run_slow
125+
def test_olmo_text_generation_with_custom_sdpa_and_kv_cache_8da4w_8we(self):
126+
model_id = "allenai/OLMo-1B-hf"
127+
tokenizer = AutoTokenizer.from_pretrained(model_id)
128+
model = ExecuTorchModelForCausalLM.from_pretrained(
129+
model_id,
130+
recipe="xnnpack",
131+
attn_implementation="custom_sdpa",
132+
use_custom_kv_cache=True,
133+
**{"qlinear": True, "qembeeding": True},
134+
)
135+
self.assertIsInstance(model, ExecuTorchModelForCausalLM)
136+
self.assertIsInstance(model.model, ExecuTorchModule)
137+
generated_text = model.text_generation(
138+
tokenizer=tokenizer,
139+
prompt="My favourite condiment is ",
140+
max_seq_len=32,
141+
)
142+
logging.info(f"\nGenerated text:\n\t{generated_text}")
143+
generated_tokens = tokenizer(generated_text, return_tensors="pt").input_ids
144+
145+
# Free memory before loading eager for quality check
146+
del model
147+
del tokenizer
148+
gc.collect()
149+
150+
self.assertTrue(check_causal_lm_output_quality(model_id, generated_tokens))

tests/models/test_modeling_qwen3.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import logging
1818
import os
1919
import subprocess
20+
import sys
2021
import tempfile
2122
import unittest
2223

@@ -35,6 +36,8 @@
3536

3637
os.environ["TOKENIZERS_PARALLELISM"] = "false"
3738

39+
is_linux_ci = sys.platform.startswith("linux") and os.environ.get("GITHUB_ACTIONS") == "true"
40+
3841

3942
class ExecuTorchModelIntegrationTest(unittest.TestCase):
4043
def __init__(self, *args, **kwargs):
@@ -67,6 +70,7 @@ def test_qwen3_export_to_executorch(self):
6770

6871
@slow
6972
@pytest.mark.run_slow
73+
@pytest.mark.skipif(is_linux_ci, reason="OOM on linux runner")
7074
def test_qwen3_text_generation(self):
7175
model_id = "Qwen/Qwen3-0.6B"
7276
model = ExecuTorchModelForCausalLM.from_pretrained(model_id, recipe="xnnpack")
@@ -91,6 +95,7 @@ def test_qwen3_text_generation(self):
9195

9296
@slow
9397
@pytest.mark.run_slow
98+
@pytest.mark.skipif(is_linux_ci, reason="OOM on linux runner")
9499
def test_qwen3_text_generation_with_custom_sdpa(self):
95100
model_id = "Qwen/Qwen3-0.6B"
96101
prompt = "Give me a short introduction to large language model."
@@ -221,3 +226,37 @@ def test_qwen3_text_generation_with_custom_sdpa_and_kv_cache(self):
221226
gc.collect()
222227

223228
self.assertTrue(check_causal_lm_output_quality(model_id, generated_tokens))
229+
230+
@slow
231+
@pytest.mark.run_slow
232+
@pytest.mark.skipif(
233+
parse(transformers.__version__) < parse("4.52.0") or parse(torchao.__version__) < parse("0.11.0"),
234+
reason="Only available on transformers >= 4.52.0 and torchao >= 0.11.0",
235+
)
236+
def test_qwen3_text_generation_with_custom_sdpa_and_kv_cache_8da4w_8we(self):
237+
model_id = "Qwen/Qwen3-0.6B"
238+
prompt = "Give me a short introduction to large language model."
239+
tokenizer = AutoTokenizer.from_pretrained(model_id)
240+
model = ExecuTorchModelForCausalLM.from_pretrained(
241+
model_id,
242+
recipe="xnnpack",
243+
attn_implementation="custom_sdpa",
244+
use_custom_kv_cache=True,
245+
**{"qlinear": True, "qembeeding": True},
246+
)
247+
self.assertIsInstance(model, ExecuTorchModelForCausalLM)
248+
self.assertIsInstance(model.model, ExecuTorchModule)
249+
generated_text = model.text_generation(
250+
tokenizer=tokenizer,
251+
prompt=prompt,
252+
max_seq_len=64,
253+
)
254+
logging.info(f"\nGenerated text:\n\t{generated_text}")
255+
generated_tokens = tokenizer(generated_text, return_tensors="pt").input_ids
256+
257+
# Free memory before loading eager for quality check
258+
del model
259+
del tokenizer
260+
gc.collect()
261+
262+
self.assertTrue(check_causal_lm_output_quality(model_id, generated_tokens))

tests/models/test_modeling_smollm.py

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,13 @@ def test_smollm_export_to_executorch(self):
4747
recipe = "xnnpack"
4848
with tempfile.TemporaryDirectory() as tempdir:
4949
subprocess.run(
50-
f"optimum-cli export executorch --model {model_id} --task {task} --recipe {recipe} --output_dir {tempdir}/executorch",
50+
f"optimum-cli export executorch \
51+
--model {model_id} \
52+
--task {task} \
53+
--recipe {recipe} \
54+
--use_custom_sdpa \
55+
--use_custom_kv_cache \
56+
--output_dir {tempdir}/executorch",
5157
shell=True,
5258
check=True,
5359
)
@@ -181,3 +187,37 @@ def test_smollm_text_generation_with_custom_sdpa_8da4w_8we(self):
181187
gc.collect()
182188

183189
self.assertTrue(check_causal_lm_output_quality(model_id, generated_tokens))
190+
191+
@slow
192+
@pytest.mark.run_slow
193+
@pytest.mark.skipif(
194+
parse(torchao.__version__) < parse("0.11.0"),
195+
reason="Only available on torchao >= 0.11.0",
196+
)
197+
def test_smollm_text_generation_with_custom_sdpa_and_kv_cache_8da4w_8we(self):
198+
model_id = "HuggingFaceTB/SmolLM2-135M"
199+
prompt = "My favourite condiment is "
200+
tokenizer = AutoTokenizer.from_pretrained(model_id)
201+
model = ExecuTorchModelForCausalLM.from_pretrained(
202+
model_id,
203+
recipe="xnnpack",
204+
attn_implementation="custom_sdpa",
205+
use_custom_kv_cache=True,
206+
**{"qlinear": True, "qembeeding": True},
207+
)
208+
self.assertIsInstance(model, ExecuTorchModelForCausalLM)
209+
self.assertIsInstance(model.model, ExecuTorchModule)
210+
generated_text = model.text_generation(
211+
tokenizer=tokenizer,
212+
prompt=prompt,
213+
max_seq_len=64,
214+
)
215+
logging.info(f"\nGenerated text:\n\t{generated_text}")
216+
generated_tokens = tokenizer(generated_text, return_tensors="pt").input_ids
217+
218+
# Free memory before loading eager for quality check
219+
del model
220+
del tokenizer
221+
gc.collect()
222+
223+
self.assertTrue(check_causal_lm_output_quality(model_id, generated_tokens))

0 commit comments

Comments
 (0)