Views
No views yet
.mlpackage converted from Qwen/Qwen2.5-1.5B-Instruct 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-qwen2.5-1.5b-coreml-anyLM-seq512 (this repo)
Fixed [1, 512] — short-form enhancement / single-sentence translation. Smallest graph. Runs on .all.grio-qwen2.5-1.5b-coreml-anyLM-seq1024
Fixed [1, 1024] — medium-context enhancement, multi-sentence translation. Runs on .all.grio-qwen2.5-1.5b-coreml-anyLM-seq2048
RangeDim [1, 1..2048] — variable-length / long-context. Must use .cpuAndNE or .cpuAndGPU; .all SIGSEGVs on the RangeDim variant.| Spec | Value |
|---|---|
| Base | Qwen/Qwen2.5-1.5B-Instruct |
| Precision | Float16 (mlprogram) |
| Context | 512 tokens, fixed shape (prompt + completion combined) |
| Inputs | inputIds, attentionMask |
| Input shape | Int32 [1, 512] |
| Output | logits: Float16 [1, 512, 151936] (rank-3, per-position) |
| Min OS | iOS 18 / macOS 15 |
| Compute | .all recommended; fixed shape is ANE-friendly on Qwen 2.5 |
| Format | .mlpackage (compiled on first load) |
| Toolchain | coremltools 9.0 + torch 2.7 + transformers 5.8.1 |
.mlpackage. Useful as a regression marker if you re-convert or quantize.cpu_and_gpu
Prompt: "The capital of France is"
Output: " Paris. The capital of France is also the capital of which country?""You are a helpful assistant. Answer concisely."
User: "What is the capital of France?"
Output: "Paris." (stops at <|im_end|> after 2 tokens)seq1024 and seq2048 variants in this collection, since the underlying weights and graph topology are the same; only the static seq dimension differs.| Compute | Predict | Load | Result |
|---|---|---|---|
.cpuAndGPU | ~538 | ~31s | ✅ Clean. |
.all | (not benchmarked in this rebuild) | — | ✅ Clean — fixed shape is ANE-friendly. |
seq2048 RangeDim variant.attentionMask = 0 on padded positions.logits is per-position, rank-3 [1, 512, 151936]. Pick the row at the last real prompt token for greedy/sampled decode..all works on this fixed-shape variant — no SIGSEGV. The .all crash documented in the seq2048 variant is specific to RangeDim graphs.generation_config.json: <|endoftext|> (id 151643) and <|im_end|> (id 151645). tokenizer.eos_token_id returns only <|im_end|>. If your runtime stops only on the single tokenizer EOS id, it may miss the document-end token in some prompts. Read the full eos_token_id list from generation_config.json for robustness. swift-transformers ≥ 1.3 handles this correctly.torch.export + coremltools.convert. Findings worth flagging for anyone converting Qwen 2.5 (or similar HF causal LMs) to a swift-transformers-compatible CoreML format:attn_implementation="sdpa". The HF default "eager" for Qwen 2.5 produces an op graph that triggers RuntimeWarning: overflow encountered in cast in coremltools/converters/mil/mil/passes/defs/optimize_repeat_ops.py:433 under RangeDim shapes, which silently corrupts logits. "sdpa" produces a cleaner op graph that lowers reliably. Fixed-shape (seq512 / seq1024) builds of Qwen 2.5 are not affected by the warning, but we still use SDPA here for consistency across the collection.torch.export.default_decompositions() — the all-decompositions mode ({}) can SIGSEGV at 1.5B+ scale under RangeDim.1import AnyLanguageModel
2
3let modelURL: URL = // path to this .mlpackage on disk
4let lm = try await CoreMLLanguageModel(
5 url: modelURL,
6 computeUnits: .all, // fixed shape — ANE-friendly
7 chatTemplateHandler: { instructions, prompt in
8 // Qwen 2.5 uses ChatML format; tokenizer.json's Jinja template applies the special tokens.
9 var messages: [Message] = []
10 if let system = instructions?.description, !system.isEmpty {
11 messages.append(["role": "system", "content": system])
12 }
13 messages.append(["role": "user", "content": prompt.description])
14 return messages
15 }
16)
17let session = LanguageModelSession(model: lm, instructions: "You are a helpful assistant.")
18let response = try await session.respond(to: "Improve this text: …")
19print(response.content)tokenizer.json, tokenizer_config.json, config.json, and generation_config.json (all bundled in this repo) as siblings of the .mlpackage on disk. swift-transformers reads the chat template from tokenizer_config.json at runtime.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 "Qwen/Qwen2.5-1.5B-Instruct",
6 torch_dtype=torch.float16,
7 attn_implementation="sdpa",
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()
17ep = torch.export.export(
18 wrapper,
19 (torch.randint(0, 151936, (1, 128), dtype=torch.int32),
20 torch.ones((1, 128), dtype=torch.int32)),
21).run_decompositions(torch.export.default_decompositions())
22
23ct.convert(
24 ep,
25 inputs=[
26 ct.TensorType(name="inputIds", shape=(1, 512), dtype=int),
27 ct.TensorType(name="attentionMask", shape=(1, 512), dtype=int),
28 ],
29 outputs=[ct.TensorType(name="logits")],
30 minimum_deployment_target=ct.target.iOS18,
31 compute_precision=ct.precision.FLOAT16,
32 convert_to="mlprogram",
33)Qwen/Qwen2.5-1.5B-Instruct by Qwen Team / Alibaba Cloud. Re-uploaded as a CoreML port; original model card terms apply.