Qwen3.5 Chat (온디바이스 LLM)
Qwen3.5-0.8B는 24 레이어(DeltaNet 18 + GatedAttention 6)의 하이브리드 DeltaNet(선형 어텐션) + GatedAttention 모델이며, MLX(Metal GPU)용 INT4와 CoreML(Neural Engine)용 INT8로 양자화됩니다. MLX를 통해 Mac에서, CoreML을 통해 iPhone과 Mac에서 스트리밍 토큰 생성으로 실행됩니다. 온디바이스 LLM이 ASR과 TTS 사이의 "두뇌" 역할을 하는 음성 파이프라인을 위해 설계되었습니다.
Qwen3.5 Chat은 ASR → LLM → TTS 체인에서 LLM 구성 요소로 SpeechCore VoicePipeline과 통합됩니다. 하이브리드 DeltaNet 아키텍처는 긴 컨텍스트에 대해 효율적인 선형 시간 어텐션을 제공합니다.
빠른 시작
import Qwen3Chat
let chat = try await Qwen35MLXChat.fromPretrained()
// 단일 응답
let response = try chat.generate("What is Swift?", systemPrompt: "Answer briefly.")
print(response)
// 스트리밍 토큰
let stream = chat.chatStream("Tell me a joke", systemPrompt: "Be funny.")
for try await token in stream {
print(token, terminator: "")
}
아키텍처
Qwen3.5-0.8B는 24 레이어의 하이브리드 모델입니다: 18개의 DeltaNet 레이어(gated delta rule 순환과 RMSNormGated를 적용한 선형 어텐션)와 6개의 GatedAttention 레이어(표준 scaled dot-product 어텐션)로 구성됩니다. MLX 백엔드는 safetensors 가중치로 Metal GPU에서 추론을 실행합니다. CoreML 백엔드는 Neural Engine에 최적화된 이중 모델 아키텍처(prefill + decode)를 사용합니다. 둘 모두 프롬프트 캐싱이 있는 KV 캐시와 구성 가능한 샘플링(temperature, top-k, top-p, 반복 페널티)을 지원합니다.
모델 I/O
| 방향 | 이름 | 형상 | 설명 |
|---|---|---|---|
| 입력 | input_ids | [1, seq_len] | 토큰 ID (Int32) |
| 입력 | attention_mask | [1, seq_len] | 어텐션 마스크 (Int32) |
| 입력 | kv_cache | 레이어별 | Key-value 캐시 상태 |
| 출력 | logits | [1, 1, 151936] | 다음 토큰 logits (Float16) |
| 출력 | kv_cache_out | 레이어별 | 업데이트된 KV 캐시 |
모델 변형
| 변형 | 양자화 | 크기 | 연산 | HuggingFace |
|---|---|---|---|---|
| Qwen3.5-0.8B Chat | INT4 | 418 MB | Metal GPU (MLX) | aufklarer/Qwen3.5-0.8B-Chat-MLX |
| Qwen3.5-0.8B Chat | INT8 | 981 MB | 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,
disableThinking: false,
maxThinkingTokens: 50
)
let response = try chat.generate("Explain gravity", sampling: config)
| 파라미터 | 기본값 | 설명 |
|---|---|---|
temperature | 0.6 | 무작위성 (0 = greedy, 1 = 창의적) |
topK | 50 | 상위 K개 후보 유지 |
topP | 0.95 | nucleus 샘플링 임계값 |
maxTokens | 512 | 최대 응답 토큰 수 |
repetitionPenalty | 1.1 | 반복 토큰에 페널티 적용 |
disableThinking | false | thinking 모드 건너뛰기 |
maxThinkingTokens | 100 | thinking 토큰 상한 |
멀티턴 대화
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() // 기록과 KV 캐시 초기화
메모리 관리
// 메모리 상태 확인
print(chat.isLoaded) // true
print(chat.memoryFootprint) // 438304768 (약 418 MB)
// 메모리 압박 시 메모리 해제
chat.unload()
print(chat.isLoaded) // false
// 필요 시 다시 로드
let chat = try await Qwen35MLXChat.fromPretrained()
iPhone에서는 TTS 추론 전에 LLM을 언로드하면 약 418 MB (INT4 MLX) 또는 약 981 MB (INT8 CoreML)가 확보되어 전체 ASR → LLM → TTS 파이프라인 실행 시 jetsam 종료를 방지합니다.
성능
| 기기 | Prefill | Decode | 토큰/초 |
|---|---|---|---|
| M2 Max | 약 50ms | 약 65ms/tok | 약 15 tok/s |
| iPhone 16 Pro | 약 1.5s | 약 450ms/tok | 약 2.2 tok/s |
변환
MLX 가중치는 MLX 변환 스크립트를 사용하여 원본 Qwen3.5-0.8B 체크포인트로부터 변환됩니다. CoreML 모델은 Neural Engine 배포용 별도 변환 스크립트를 사용합니다. 사전 변환된 가중치는 HuggingFace의 aufklarer/Qwen3.5-0.8B-Chat-MLX (INT4: 418 MB)와 aufklarer/Qwen3.5-0.8B-Chat-CoreML (INT8: 981 MB)에서 제공됩니다.