Views
No views yet
.mlpackage converted from google/gemma-3-1b-it for use with HuggingFace's AnyLanguageModel Swift framework and swift-transformers ≥ 1.0.inputIds / attentionMask / logits convention required by swift-transformers 1.x LanguageModel. Drop-in compatible with CoreMLLanguageModel(url:computeUnits:chatTemplateHandler:).grio-gemma-3-1b-coreml-anyLM-seq512
Fixed [1, 512] — short-form enhancement / single-sentence translation. Always pays for full 512 positions per step.grio-gemma-3-1b-coreml-anyLM-seq1024
Fixed [1, 1024] — medium-context post-processing. Always pays for full 1024 positions per step.grio-gemma-3-1b-coreml-anyLM-seq2048 (this repo)
RangeDim [1, 1..2048] — recommended production variant. Variable-length translation / long-context. Per-step cost scales with real prompt length, so for typical product prompts (<200 tokens) this is the fastest of the three. Must use .cpuAndGPU; .cpuAndNE rejects, .cpuOnly produces wrong output, and .all works but is slow.| Spec | Value |
|---|---|
| Base | google/gemma-3-1b-it |
| Precision | Float16 (mlprogram) |
| Context | 1-2048 tokens, flexible RangeDim(1, 2048) |
| Inputs | inputIds, attentionMask |
| Input shape | Int32 [1, <=2048] |
| Output | logits: Float16 [1, seq_len, 262144] (rank-3, per-position) |
| Min OS | iOS 18 / macOS 15 |
| Compute | .cpuAndGPU required; do not use .cpuAndNE or .cpuOnly |
| Format | .mlpackage (compiled on first load) |
| Toolchain | coremltools 9.0 + torch 2.7 + transformers 5.8.1 |
.mlpackage under .cpuAndGPU. Token IDs are byte-identical to PyTorch FP16 reference (model.generate(do_sample=False, use_cache=True))."You are a helpful assistant. Answer concisely."
User: "What is the capital of France?"
Output: "Paris." (stops at <end_of_turn> after 3 tokens)"You are a French translator. Translate the user message to French. Output only the translation."
User: "The quick brown fox jumps over the lazy dog."
Output: "Le rapide renard brun saute par-dessus le chien paresseux.""You are a German translator. Translate the user message to German. Output only the translation."
User: "I would like to order a coffee, please."
Output: "Ich möchte einen Kaffee bestellen.""Rewrite the user's text in clear formal English. Output only the rewrite."
User: "ok so the guy was like really mad cuz his package didnt show up"
Output: "The individual expressed considerable frustration as his package had not arrived.""You are a transcription editor. Improve the grammar and punctuation of the user's text. Output only the improved text."
User: "so um like i was thinking we should go to the store maybe tomorrow if its not raining"
Output: "So, um, I was thinking we should go to the store maybe tomorrow if it's not raining."| Compute | Predict | Load | Result |
|---|---|---|---|
.cpuAndGPU | ~600 | ~12s | ✅ Clean. Production-recommended. |
.all | ~3700 | ~65s | ✅ Clean output but ANE compilation fails internally; CoreML silently falls back to GPU/CPU. Slow. |
.cpuAndNE | — | — | ❌ RuntimeError: Espresso exception: "Invalid blob shape": Data-dependent shapes were disabled — ANE doesn't support RangeDim + sliding-window rotary embeddings. |
.cpuOnly | ~1100 | ~14s | ⚠️ Silently produces wrong output (top-1 = '#' token id 236865 instead of 'Paris') — BNNS FP16 precision interacts badly with RangeDim shape handling. Do not use. |
.cpuOnly silently produces wrong output on this RangeDim variant. Not NaN — wrong. The model returns valid-looking but incorrect token IDs. Always use .cpuAndGPU for this variant. The fixed-shape seq512/seq1024 variants in this collection do not have this issue (.cpuOnly is clean on those)..cpuAndNE is rejected with an explicit error about data-dependent shapes. Gemma 3's combination of sliding-window attention and RangeDim input shapes produces ops the ANE compiler refuses.<eos> (id 1) for general end-of-sequence and <end_of_turn> (id 106) for chat-turn termination. generation_config.json lists both. If your runtime stops only on tokenizer.eos_token_id (which returns <eos>), the model will decode past <end_of_turn> into out-of-distribution territory and produce multilingual gibberish that looks like graph corruption but isn't. Read the full eos_token_id list from generation_config.json and stop on any of them. swift-transformers ≥ 1.3 handles this correctly.chat_template.jinja (a separate file from tokenizer_config.json). swift-transformers ≥ 1.3 reads it correctly via Hub.swift. Older callers that look for an inline chat_template key in tokenizer_config.json will not find one.logits shape metadata is empty in the .mlpackage description (a coremltools artifact for RangeDim outputs). Verify at runtime with a real predict() — the actual output is rank-3 [1, seq_len, 262144] and works with swift-transformers' assert(scores.rank == 3).torch.export + coremltools.convert. Findings worth flagging for others converting Gemma 3 (or similar HF causal LMs) to CoreML:attn_implementation="sdpa". The HF default "eager" for Gemma 3 may produce a corrupted graph under RangeDim (we saw this on Qwen 2.5 RangeDim builds). SDPA gives a cleaner, fewer-op MIL graph that lowers reliably.torch.export.default_decompositions() for run_decompositions. The all-decompositions mode ({}) can SIGSEGV inside optimize_repeat_ops at 1B+ scale on RangeDim graphs.optimize_repeat_ops.py:433 RuntimeWarning: overflow encountered in cast fires during conversion of this model. Despite the warning, output is byte-identical to PyTorch FP16 reference under .cpuAndGPU. The warning indicates internal range arithmetic overflow but does not corrupt the produced graph for Gemma 3 + SDPA. Don't reflexively reconvert on seeing it — verify with a PyTorch comparison instead.chat_template.jinja must be bundled alongside the .mlpackage. So must generation_config.json (for the multi-id EOS list), special_tokens_map.json, added_tokens.json, and tokenizer.model. This repo includes all of them.1import AnyLanguageModel
2
3let modelURL: URL = // path to this .mlpackage on disk
4let lm = try await CoreMLLanguageModel(
5 url: modelURL,
6 computeUnits: .cpuAndGPU, // REQUIRED for this RangeDim variant — see Runtime gotchas
7 chatTemplateHandler: { instructions, prompt in
8 // Gemma 3 uses <start_of_turn>...<end_of_turn> chat template; tokenizer.json's
9 // Jinja template (loaded by swift-transformers from chat_template.jinja) applies it.
10 var messages: [Message] = []
11 if let system = instructions?.description, !system.isEmpty {
12 messages.append(["role": "system", "content": system])
13 }
14 messages.append(["role": "user", "content": prompt.description])
15 return messages
16 }
17)
18let session = LanguageModelSession(model: lm, instructions: "You are a French translator. Output only the translation.")
19let response = try await session.respond(to: "The capital of France is Paris.")
20print(response.content)tokenizer.json, tokenizer_config.json, config.json, chat_template.jinja, generation_config.json, special_tokens_map.json, added_tokens.json, and tokenizer.model (all bundled in this repo) as siblings of the .mlpackage on disk.coremltools==9.0, torch==2.7.0, transformers==5.8.1. Approximate single-call recipe:1import coremltools as ct, torch, torch.nn as nn
2from transformers import AutoModelForCausalLM
3
4model = AutoModelForCausalLM.from_pretrained(
5 "google/gemma-3-1b-it",
6 torch_dtype=torch.float16,
7 attn_implementation="sdpa", # see Conversion notes
8)
9model.eval()
10
11class Wrapper(nn.Module):
12 def __init__(self, m): super().__init__(); self.m = m
13 def forward(self, inputIds, attentionMask):
14 return self.m(input_ids=inputIds, attention_mask=attentionMask, use_cache=False).logits
15
16wrapper = Wrapper(model).eval()
17seq = torch.export.Dim("sequence_length", min=1, max=2048)
18ep = torch.export.export(
19 wrapper,
20 (torch.randint(0, 262144, (1, 128), dtype=torch.int32),
21 torch.ones((1, 128), dtype=torch.int32)),
22 dynamic_shapes={"inputIds": {1: seq}, "attentionMask": {1: seq}},
23).run_decompositions(torch.export.default_decompositions()) # NOT {}
24
25ct.convert(
26 ep,
27 inputs=[
28 ct.TensorType(name="inputIds", shape=(1, ct.RangeDim(1, 2048)), dtype=int),
29 ct.TensorType(name="attentionMask", shape=(1, ct.RangeDim(1, 2048)), dtype=int),
30 ],
31 outputs=[ct.TensorType(name="logits")],
32 minimum_deployment_target=ct.target.iOS18,
33 compute_precision=ct.precision.FLOAT16,
34 convert_to="mlprogram",
35)google/gemma-3-1b-it by Google DeepMind. Re-uploaded as a CoreML port; original model card terms apply. By using this model you agree to Google's Gemma Terms of Use and the Prohibited Use Policy.