Qwen3.5 Chat (локальный LLM)
Qwen3.5-0.8B — это гибридная модель DeltaNet (linear attention) + GatedAttention с 24 слоями (18 DeltaNet + 6 GatedAttention), квантизированная до INT4 для MLX (Metal GPU) и INT8 для CoreML (Neural Engine). Работает на Mac через MLX или на iPhone и Mac через CoreML с потоковой генерацией токенов. Создана для голосовых пайплайнов, где локальный LLM служит «мозгом» между ASR и TTS.
Qwen3.5 Chat интегрируется с SpeechCore VoicePipeline как LLM-компонент в цепочках ASR → LLM → TTS. Гибридная архитектура DeltaNet обеспечивает эффективное attention с линейной сложностью для длинных контекстов.
Быстрый старт
import Qwen3Chat
let chat = try await Qwen35MLXChat.fromPretrained()
// Single response
let response = try chat.generate(messages: [
ChatMessage(role: .system, content: "Answer briefly."),
ChatMessage(role: .user, content: "What is Swift?")
])
print(response)
// Streaming tokens
let stream = chat.generateStream(messages: [
ChatMessage(role: .system, content: "Be funny."),
ChatMessage(role: .user, content: "Tell me a joke")
])
for try await token in stream {
print(token, terminator: "")
}
Архитектура
Qwen3.5-0.8B — это гибридная модель с 24 слоями: 18 слоёв DeltaNet (linear attention с gated delta rule recurrence и RMSNormGated) и 6 слоёв GatedAttention (стандартное scaled dot-product attention). Бэкенд MLX выполняет инференс на Metal GPU с весами в safetensors. Бэкенд CoreML использует архитектуру с двумя моделями (prefill + decode), оптимизированную под Neural Engine. Оба поддерживают KV cache с кешированием подсказки и настраиваемым сэмплированием (temperature, top-k, top-p, штраф за повторения).
I/O модели
| Направление | Имя | Форма | Описание |
|---|---|---|---|
| Вход | input_ids | [1, seq_len] | Token ID (Int32) |
| Вход | attention_mask | [1, seq_len] | Attention-маска (Int32) |
| Вход | kv_cache | per-layer | Состояние KV-кеша |
| Выход | logits | [1, 1, 151936] | Логиты следующего токена (Float16) |
| Выход | kv_cache_out | per-layer | Обновлённый KV-кеш |
Варианты модели
| Вариант | Квантизация | Размер | Вычисления | HuggingFace |
|---|---|---|---|---|
| Qwen3.5-0.8B Chat | INT4 | 418 МБ | Metal GPU (MLX) | aufklarer/Qwen3.5-0.8B-Chat-MLX |
| Qwen3.5-0.8B Chat | INT8 | 981 МБ | Neural Engine (CoreML) | aufklarer/Qwen3.5-0.8B-Chat-CoreML |
Конфигурация сэмплирования
let config = ChatSamplingConfig(
temperature: 0.7,
topK: 40,
topP: 0.9,
maxTokens: 128,
repetitionPenalty: 1.1
)
let response = try chat.generate(
messages: [ChatMessage(role: .user, content: "Explain gravity")],
sampling: config
)
| Параметр | По умолчанию | Описание |
|---|---|---|
temperature | 0.6 | Случайность (0 = жадный, 1 = креативный) |
topK | 50 | Оставить top K кандидатов |
topP | 0.95 | Порог nucleus sampling |
maxTokens | 512 | Максимум токенов ответа |
repetitionPenalty | 1.1 | Штраф за повторяющиеся токены |
disableThinking | false | Пропустить режим размышления |
maxThinkingTokens | 100 | Ограничение токенов размышления |
Многошаговый диалог
let chat = try await Qwen35MLXChat.fromPretrained()
let history = [
ChatMessage(role: .system, content: "Remember the user's name."),
ChatMessage(role: .user, content: "My name is Alex"),
ChatMessage(role: .assistant, content: "Nice to meet you, Alex!"),
ChatMessage(role: .user, content: "What's my name?")
]
let response = try chat.generate(messages: history)
print(response) // "Your name is Alex!"
chat.resetState() // Clear inference state for a new conversation
Управление памятью
// Check memory state
print(chat.isLoaded) // true
print(chat.memoryFootprint) // 438304768 (~418 MB)
// Free memory under pressure
chat.unload()
print(chat.isLoaded) // false
// Reload when needed
let chat = try await Qwen35MLXChat.fromPretrained()
На iPhone выгрузка LLM перед инференсом TTS освобождает ~418 МБ (INT4 MLX) или ~981 МБ (INT8 CoreML), предотвращая jetsam-завершение при работе полных пайплайнов ASR → LLM → TTS.
Производительность
| Устройство | Prefill | Decode | Токенов/сек |
|---|---|---|---|
| M2 Max | ~50 мс | ~65 мс/ток | ~15 ток/с |
| iPhone 16 Pro | ~1.5 с | ~450 мс/ток | ~2.2 ток/с |
Конвертация
Веса MLX конвертируются из оригинального чекпоинта Qwen3.5-0.8B через скрипт конвертации MLX. CoreML-модели используют отдельный скрипт конвертации для развёртывания на Neural Engine. Предварительно сконвертированные веса доступны на HuggingFace: aufklarer/Qwen3.5-0.8B-Chat-MLX (INT4: 418 МБ) и aufklarer/Qwen3.5-0.8B-Chat-CoreML (INT8: 981 МБ).