Qwen3.5 Chat (LLM embarqué)
Qwen3.5-0.8B est un modèle hybride DeltaNet (attention linéaire) + GatedAttention avec 24 couches (18 DeltaNet + 6 GatedAttention), quantifié en INT4 pour MLX (GPU Metal) et en INT8 pour CoreML (Neural Engine). S'exécute sur Mac via MLX ou sur iPhone et Mac via CoreML avec génération de tokens en streaming. Conçu pour les pipelines vocaux où un LLM embarqué fournit le « cerveau » entre ASR et TTS.
Qwen3.5 Chat s'intègre à la VoicePipeline de SpeechCore comme composant LLM dans les chaînes ASR → LLM → TTS. L'architecture hybride DeltaNet offre une attention efficace en temps linéaire pour les contextes longs.
Démarrage rapide
import Qwen3Chat
let chat = try await Qwen35MLXChat.fromPretrained()
// Réponse unique
let response = try chat.generate("What is Swift?", systemPrompt: "Answer briefly.")
print(response)
// Tokens en streaming
let stream = chat.chatStream("Tell me a joke", systemPrompt: "Be funny.")
for try await token in stream {
print(token, terminator: "")
}
Architecture
Qwen3.5-0.8B est un modèle hybride à 24 couches : 18 couches DeltaNet (attention linéaire avec récurrence gated delta rule et RMSNormGated) et 6 couches GatedAttention (attention scaled dot-product standard). Le backend MLX exécute l'inférence sur le GPU Metal avec des poids safetensors. Le backend CoreML utilise une architecture à deux modèles (prefill + decode) optimisée pour le Neural Engine. Les deux prennent en charge le cache KV avec mise en cache du prompt et un échantillonnage configurable (température, top-k, top-p, pénalité de répétition).
E/S du modèle
| Direction | Nom | Forme | Description |
|---|---|---|---|
| Entrée | input_ids | [1, seq_len] | IDs de tokens (Int32) |
| Entrée | attention_mask | [1, seq_len] | Masque d'attention (Int32) |
| Entrée | kv_cache | par couche | État du cache clé-valeur |
| Sortie | logits | [1, 1, 151936] | Logits du prochain token (Float16) |
| Sortie | kv_cache_out | par couche | Cache KV mis à jour |
Variantes du modèle
| Variante | Quantification | Taille | Calcul | HuggingFace |
|---|---|---|---|---|
| Qwen3.5-0.8B Chat | INT4 | 418 Mo | GPU Metal (MLX) | aufklarer/Qwen3.5-0.8B-Chat-MLX |
| Qwen3.5-0.8B Chat | INT8 | 981 Mo | Neural Engine (CoreML) | aufklarer/Qwen3.5-0.8B-Chat-CoreML |
Configuration de l'échantillonnage
let config = ChatSamplingConfig(
temperature: 0.7,
topK: 40,
topP: 0.9,
maxTokens: 128,
repetitionPenalty: 1.1,
disableThinking: false,
maxThinkingTokens: 50
)
let response = try chat.generate("Explain gravity", sampling: config)
| Paramètre | Par défaut | Description |
|---|---|---|
temperature | 0,6 | Aléatoire (0 = glouton, 1 = créatif) |
topK | 50 | Conserver les K meilleurs candidats |
topP | 0,95 | Seuil d'échantillonnage nucleus |
maxTokens | 512 | Tokens maximum par réponse |
repetitionPenalty | 1,1 | Pénalise les tokens répétés |
disableThinking | false | Sauter le mode réflexion |
maxThinkingTokens | 100 | Plafonner les tokens de réflexion |
Conversation multi-tours
let chat = try await Qwen35MLXChat.fromPretrained()
let r1 = try chat.generate("My name is Alex", systemPrompt: "Remember the user's name.")
print(r1) // "Nice to meet you, Alex!"
let r2 = try chat.generate("What's my name?")
print(r2) // "Your name is Alex!"
chat.resetConversation() // Efface l'historique et le cache KV
Gestion de la mémoire
// Vérifier l'état mémoire
print(chat.isLoaded) // true
print(chat.memoryFootprint) // 438304768 (~418 Mo)
// Libérer la mémoire en cas de pression
chat.unload()
print(chat.isLoaded) // false
// Recharger au besoin
let chat = try await Qwen35MLXChat.fromPretrained()
Sur iPhone, décharger le LLM avant l'inférence TTS libère environ 418 Mo (INT4 MLX) ou 981 Mo (INT8 CoreML), empêchant une terminaison jetsam lors de l'exécution de pipelines complets ASR → LLM → TTS.
Performance
| Appareil | Prefill | Decode | tok/s |
|---|---|---|---|
| M2 Max | ~50 ms | ~65 ms/tok | ~15 tok/s |
| iPhone 16 Pro | ~1,5 s | ~450 ms/tok | ~2,2 tok/s |
Conversion
Les poids MLX sont convertis depuis le checkpoint Qwen3.5-0.8B original à l'aide du script de conversion MLX. Les modèles CoreML utilisent un script de conversion séparé pour le déploiement sur Neural Engine. Les poids pré-convertis sont disponibles sur HuggingFace : aufklarer/Qwen3.5-0.8B-Chat-MLX (INT4 : 418 Mo) et aufklarer/Qwen3.5-0.8B-Chat-CoreML (INT8 : 981 Mo).