Skip to content

Commit 550fe06

Browse files
authored
feat(gemma): add gemma-3-270m and gemma-3-12b manifests and refuse fp16 for Gemma 3 (1327)
## Implementation Manifests only for the two widths. The one code change is the fp16 refusal.
1 parent 9d65d3b commit 550fe06

4 files changed

Lines changed: 80 additions & 0 deletions

File tree

apps/benchmark/performance/release.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ excluded_profiles:
8888
Functional and Hugging Face reference-parity qualification is present,
8989
but the release-performance workload and receipt were collected only for
9090
gemma-2-2b, which exercises the same builder and runtime path.
91+
- model: gemma-3-270m
92+
reason: *gemma3_performance_exclusion
9193
- model: gemma-3-1b
9294
reason: >-
9395
Functional and Hugging Face reference-parity qualification is present,

families/gemma/model.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,20 @@ def _checkpoint_gated_activation(config: ModelConfig) -> str:
249249
# this family has, so the prefix let them build a full-attention graph and
250250
# generate quietly wrong text rather than being refused.
251251
_GEMMA3_MODEL_TYPES = frozenset({"gemma3", "gemma3_text"})
252+
# Gemma 3 activations do not fit fp16. Running the reference in fp32 and taking
253+
# the largest absolute value leaving each decoder layer, against the fp16
254+
# maximum of 65504:
255+
#
256+
# gemma-3-270m peak 102956 11 of 18 layers over
257+
# gemma-3-1b peak 61040 0 of 26 layers over (a 7% margin)
258+
# gemma-3-4b peak 298680 29 of 34 layers over
259+
#
260+
# The two that overflow emit token 0 repeatedly. The 1B stays inside the range
261+
# on one prompt by 7%, which is luck rather than headroom, so fp16 is refused
262+
# for the generation rather than per width. Gemma 2 peaks at 4060 and keeps it.
263+
_FP16_UNSAFE_MODEL_TYPES = _GEMMA3_MODEL_TYPES
264+
265+
252266
_SUPPORTED_MODEL_TYPES = frozenset({"gemma", "gemma2"}) | _GEMMA3_MODEL_TYPES
253267

254268

@@ -345,6 +359,12 @@ def build(request: "BuildRequest", writer: "BundleWriter") -> None:
345359
precision = str(request.precision).lower()
346360
if precision not in {"fp32", "fp16", "bf16"}:
347361
raise ValueError("Gemma precision must be fp32, fp16, or bf16")
362+
if precision == "fp16" and str(config.model_type).lower() in _FP16_UNSAFE_MODEL_TYPES:
363+
raise NotImplementedError(
364+
f"gemma does not support fp16 for {config.model_type!r}: its activations "
365+
"exceed the fp16 range and the engine returns a single repeated token; "
366+
"use bf16 or fp32"
367+
)
348368
max_sequence_length = _positive_int(
349369
request.max_sequence_length or min(config.max_position_embeddings, 256),
350370
"max_sequence_length",
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"name": "gemma-3-270m",
3+
"hf_id": "google/gemma-3-270m-it",
4+
"bundle": "gemma-3-270m.bundle",
5+
"family": "gemma",
6+
"task": "text_generation",
7+
"precision": "bf16",
8+
"trust_remote_code": false,
9+
"testcases": [
10+
{
11+
"name": "gemma-3-270m",
12+
"premerge": true,
13+
"reference_precision": "fp32",
14+
"prompt": "What is the capital of France? Answer with just the name.",
15+
"max_new_tokens": 8,
16+
"use_chat_template": true,
17+
"enable_thinking": false
18+
}
19+
],
20+
"max_sequence_length": 256,
21+
"tensor_parallel_size": 1
22+
}

families/gemma/tests/test_model_type_gate.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,39 @@ def test_the_supported_generations_pass_the_gate(tmp_path: Path) -> None:
9696
with pytest.raises(Exception) as caught: # noqa: PT011 - any later failure will do
9797
_build(directory)
9898
assert "does not support model_type" not in str(caught.value)
99+
100+
101+
def test_gemma3_refuses_fp16(tmp_path: Path) -> None:
102+
"""Gemma 3 activations exceed the fp16 range, so fp16 is refused.
103+
104+
Measured on the reference in fp32, largest absolute value leaving a decoder
105+
layer against the fp16 maximum of 65504: gemma-3-270m peaks at 102956 and
106+
gemma-3-4b at 298680, both of which overflow and make the engine emit token
107+
0 repeatedly. gemma-3-1b peaks at 61040, inside the range by 7%, which is
108+
luck rather than headroom.
109+
"""
110+
for model_type in ("gemma3", "gemma3_text"):
111+
directory = _model_dir(tmp_path / f"fp16-{model_type}", model_type)
112+
with pytest.raises(NotImplementedError, match="does not support fp16"):
113+
_build_with(directory, precision="fp16")
114+
115+
116+
def test_gemma2_keeps_fp16(tmp_path: Path) -> None:
117+
"""Gemma 2 peaks at 4060, sixteen times inside the fp16 range."""
118+
directory = _model_dir(tmp_path / "fp16-gemma2", "gemma2")
119+
with pytest.raises(Exception) as caught: # noqa: PT011 - a later failure is fine
120+
_build_with(directory, precision="fp16")
121+
assert "does not support fp16" not in str(caught.value)
122+
123+
124+
def _build_with(model_dir: Path, *, precision: str) -> None:
125+
build_family(
126+
BuildRequest(
127+
model_dir=model_dir,
128+
output_path=model_dir / "out.bundle",
129+
family="gemma",
130+
task="text_generation",
131+
precision=precision,
132+
),
133+
writer=None,
134+
)

0 commit comments

Comments
 (0)