Views
No views yet
coreai-torch (LLMs: coreai.llm.export) into .aimodel bundles that run on the GPU or the Neural Engine, e.g. Qwen3-8B 4-bit decodes at 94 tok/s on an M4 Max GPU, MLX 90 under the same protocol (apple-silicon-llm-bench, macOS 27 beta, 2026-06)..aimodel)Qwen/Qwen3-VL-2B-Instruct converted to .aimodel, running
image+text → text fully on the GPU via Apple's coreai-pipelined engine —
zero custom kernels.

import CoreAIOps; no session, no model plumbing, downloads on first use):let caption = try await CoreAI.caption(imageAt: url)1git clone https://github.com/john-rocky/coreai-kit
2open coreai-kit/Examples/VLChat/VLChat.xcodeproj
3# → Run, then pick "Qwen3-VL 2B" in the model picker
4
5# agents / headless (macOS):
6cd coreai-kit/Examples/VLChat
7swift run vlchat-cli --model qwen3-vl-2b --image sample.jpg --prompt "What is in this image?"1import CoreAIKit
2import FoundationModels
3
4let vlm = try await KitVisionModel(catalog: "qwen3-vl-2b")
5let session = LanguageModelSession(model: vlm)
6let image = try ImageFile.load(imageURL) // any image file → CGImage + EXIF orientation
7let reply = try await session.respond(to: Prompt {
8 prompt
9 Attachment(image.cgImage, orientation: image.orientation)
10})
11// reply.content: the answer about the image, generated fully on-deviceExamples/VLChat/Sources/QuickStart.swift
— this exact code as one typed function, no UI; the CLI is an argument shell over it, and
the GUI drives the same KitVisionModel(catalog:) behind a LanguageModelSession.
Multi-turn about the same image? Hold the LanguageModelSession and call respond(to:)
per turn. The photo picker / file chooser is your app's own chrome — ImageFile.load
(kit API) turns any image file into model input.https://github.com/john-rocky/coreai-kit → product CoreAIKitNSPhotoLibraryUsageDescription — only if you use PhotosPickercom.apple.developer.kernel.increased-memory-limitdownloadProgress callback)| platform | prefill tok/s | decode tok/s | numerics |
|---|---|---|---|
| M4 Max (macOS 27 beta) | 191.0 | 187.6 | full multimodal oracle gates vs fp32-HF PASS |
| iPhone 17 Pro (iOS 27 beta, settled) | 33.9 | 33.3 | text + image prompts 24/24 × 8 runs, token-identical to Mac (~92% of the naive BW ceiling) |
| path | what | size |
|---|---|---|
gpu-pipelined/qwen3_vl_2b_instruct_decode_int8hu_s1/ | text decoder LanguageBundle (SHIP: int8 per-block-32 body + untied absmax int8 head; tokenizer + metadata included) | 2.3 GB |
gpu-pipelined/qwen3_vl_2b_instruct_vision/ | fixed-grid vision encoder (448×448 → 196 tokens + DeepStack), fp16 | 0.77 GB |
gpu-pipelined/qwen3_vl_2b_instruct_decode_int8lin_s1/ | decoder alt: tied fp16 head (slower, smaller-RAM-spike option) | 2.0 GB |
MTLBuffers, ~3 MB),<|image_pad|> ids become extension ids vocab + slot;
the graph selects text-table vs image-embed rows per token and applies
the three DeepStack adds the same way,get_rope_index, 28/28 layers) → .aimodel GPU gates →
engine ≡ python 24/24 → device 24/24.apps/CoreAIChat (iOS) has a Qwen3-VL mode with a photo picker
and downloads this repo in-app. For the run contract (S=1 prefill,
COREAI_CHUNK_THRESHOLD=1, never engine.warmup()), see
knowledge/pipelined-engine.md.conversion/export_qwen3_vl_pipelined.py int8hu.