據 AlphaMoat 統計,截至 2026-09,MLX Swift LM Expert 累計下載 3,683 次、獲 3 個星標,在全部 5,078 個 AI 技能中排名第 2,933 位,在「開發程式設計」分類(577 個)中排名第 379 位。
| 平台 | 累計安裝 | 累計下載 | 星標 | 評論 |
|---|---|---|---|---|
| ClawHub ↗ | 91 | 3683 | 3 | - |
| SkillHub ↗ | 266 | 3022 | 3 | — |
各平台的計數口徑不同,統計時間不一致。
mlx-swift-lm 是一個 Swift 包,使用 MLX 在 Apple Silicon 上執行 LLM 與 VLM,支援本地推理、流式生成、工具/函式呼叫、LoRA/DoRA 微調和文字 embeddings(可用於 RAG/語義搜尋)。涵蓋 ChatSession(自動管理對話歷史與 KV cache 的簡化聊天 API)、ModelContainer(執行緒安全的模型封裝)、GenerateParameters(maxTokens、temperature、滑動視窗 maxKVSize、4/8 bit 量化快取等)、VLM 圖片/影片輸入、prompt 快取與歷史恢復,以及已廢棄 API 的遷移對照。注意執行緒安全:ModelContainer 是 Sendable 的,但 ChatSession 不是執行緒安全的(應在單個 task 中使用),MLXArray 不可跨隔離邊界傳遞。模型從 HuggingFace 自動下載;主文列出的 Llama、Qwen、Gemma 等僅為示例而非窮舉。
資料釋出於 2026-10-27
ChatSession 做多輪對話與流式生成VLMModelFactory 載入視覺語言模型處理圖片/影片輸入以下是根據技能文件生成的示例,不代表實際執行結果。
2026-09 起統計方法調整:同名技能按作者分別統計,並覆蓋全部技能。圖中虛線為調整前的月份,與之後的資料不直接比較,也不計算跨越調整的增長。
| 月份 | 累計下載 | 環比 | 星標 |
|---|---|---|---|
| 2026-09 | 3683 | — | 3 |
| 2026-08 | 2747 | +2.4% | 3 |
| 2026-07 | 2682 | +9.9% | 3 |
| 2026-06 | 2441 | +5.7% | 3 |
| 2026-05 | 2310 | — | 3 |
| 2026-03 | 2068 | — | 3 |
以下是作者釋出的原始檔案,按純文字顯示,本站未做修改或稽核;其中的連結不可點選,命令請核實後再執行。抓取於 2026-10-23。
--- name: swift-mlx-lm description: MLX Swift LM - Run LLMs and VLMs on Apple Silicon using MLX. Covers local inference, streaming, tool calling, LoRA fine-tuning, and embeddings. triggers: - mlx - mlx-swift - mlx-lm - apple silicon llm - local llm swift - vision language model swift
- lora training swift
---
# mlx-swift-lm Skill
## 1. Overview & Triggers
mlx-swift-lm is a Swift package for running Large Language Models (LLMs) and Vision-Language Models (VLMs) on Apple Silicon using MLX. It supports local inference, fine-tuning via LoRA/DoRA, and embeddings generation.
### When to Use This Skill
- Running LLM/VLM inference on macOS/iOS with Apple Silicon
- Streaming text generation from local models
- Vision tasks with images/video (VLMs)
- Tool calling / function calling with models
- LoRA adapter training and fine-tuning
- Text embeddings for RAG/semantic search
### Architecture Overview
```
MLXLMCommon - Core infrastructure (ModelContainer, ChatSession, KVCache, etc.)
MLXLLM - Text-only LLM support (Llama, Qwen, Gemma, Phi, DeepSeek, etc. - examples, not exhaustive)
MLXVLM - Vision-Language Models (Qwen2-VL, PaliGemma, Gemma3, etc. - examples, not exhaustive)
Embedders - Embedding models (BGE, Nomic, MiniLM)
```
## 2. Key File Reference
| Purpose | File Path |
|---------|-----------|
| Thread-safe model wrapper | `Libraries/MLXLMCommon/ModelContainer.swift` |
| Simplified chat API | `Libraries/MLXLMCommon/ChatSession.swift` |
| Generation & streaming | `Libraries/MLXLMCommon/Evaluate.swift` |
| KV cache types | `Libraries/MLXLMCommon/KVCache.swift` |
| Model configuration | `Libraries/MLXLMCommon/ModelConfiguration.swift` |
| Chat message types | `Libraries/MLXLMCommon/Chat.swift` |
| Tool call processing | `Libraries/MLXLMCommon/Tool/ToolCallFormat.swift` |
| Concurrency utilities | `Libraries/MLXLMCommon/Utilities/SerialAccessContainer.swift` |
| LLM factory & registry | `Libraries/MLXLLM/LLMModelFactory.swift` |
| VLM factory & registry | `Libraries/MLXVLM/VLMModelFactory.swift` |
| LoRA configuration | `Libraries/MLXLMCommon/Adapters/LoRA/LoRAContainer.swift` |
| LoRA training | `Libraries/MLXLLM/LoraTrain.swift` |
## 3. Quick Start
### LLM Chat (Simplest API)
```swift
import MLXLLM
import MLXLMCommon
// Load model (downloads from HuggingFace automatically)
let modelContainer = try await LLMModelFactory.shared.loadContainer(
configuration: .init(id: "mlx-community/Qwen3-4B-4bit")
)
// Create chat session
let session = ChatSession(modelContainer)
// Single response
let response = try await session.respond(to: "What is Swift?")
print(response)
// Streaming response
for try await chunk in session.streamResponse(to: "Explain concurrency") {
print(chunk, terminator: "")
}
```
### VLM with Image
```swift
import MLXVLM
import MLXLMCommon
let modelContainer = try await VLMModelFactory.shared.loadContainer(
configuration: .init(id: "mlx-community/Qwen2-VL-2B-Instruct-4bit")
)
let session = ChatSession(modelContainer)
// With image (video is also an optional parameter)
let image = UserInput.Image.url(imageURL)
let response = try await session.respond(
to: "Describe this image",
image: image,
video: nil // Optional video parameter
)
```
### Embeddings
```swift
import Embedders
// Note: Embedders uses loadModelContainer() helper (not a factory pattern)
let container = try await loadModelContainer(
configuration: ModelConfiguration(id: "mlx-community/bge-small-en-v1.5-mlx")
)
let embeddings = await container.perform { model, tokenizer, pooler in
let tokens = tokenizer.encode(text: "Hello world")
let input = MLXArray(tokens).expandedDimensions(axis: 0)
let output = model(input)
let pooled = pooler(output, normalize: true)
eval(pooled)
return pooled
}
```
## 4. Primary Workflow: LLM Inference
### ChatSession API (Recommended)
`ChatSession` manages conversation history and KV cache automatically:
```swift
let session = ChatSession(
modelContainer,
instructions: "You are a helpful assistant", // System prompt
generateParameters: GenerateParameters(
maxTokens: 500,
temperature: 0.7
)
)
// Multi-turn conversation (history preserved automatically)
let r1 = try await session.respond(to: "What is 2+2?")
let r2 = try await session.respond(to: "And if you multiply that by 3?")
// Clear session to start fresh
await session.clear()
```
### Streaming with generate()
For lower-level control, use `generate()` directly:
```swift
let input = try await modelContainer.prepare(input: UserInput(prompt: .text("Hello")))
let stream = try await modelContainer.generate(input: input, parameters: GenerateParameters())
for await generation in stream {
switch generation {
case .chunk(let text):
print(text, terminator: "")
case .info(let info):
print("\n\(info.tokensPerSecond) tok/s")
case .toolCall(let call):
// Handle tool call
break
}
}
```
### Tool Calling
```swift
// 1. Define tool
struct WeatherInput: Codable { let location: String }
struct WeatherOutput: Codable { let temperature: Double; let conditions: String }
let weatherTool = Tool<WeatherInput, WeatherOutput>(
name: "get_weather",
description: "Get current weather",
parameters: [.required("location", type: .string, description: "City name")]
) { input in
WeatherOutput(temperature: 22.0, conditions: "Sunny")
}
// 2. Include tool schema in request
let input = UserInput(
prompt: .text("What's the weather in Tokyo?"),
tools: [weatherTool.schema]
)
// 3. Handle tool calls in generation stream
for await generation in try await modelContainer.generate(input: input, parameters: params) {
switch generation {
case .chunk(let text): print(text)
case .toolCall(let call):
let result = try await call.execute(with: weatherTool)
print("Weather: \(result.conditions)")
case .info: break
}
}
```
See [references/tool-calling.md](references/tool-calling.md) for multi-turn and feeding results back.
### GenerateParameters
```swift
let params = GenerateParameters(
maxTokens: 1000, // nil = unlimited
maxKVSize: 4096, // Sliding window (uses RotatingKVCache)
kvBits: 4, // Quantized cache (4 or 8 bit)
temperature: 0.7, // 0 = greedy/argmax
topP: 0.9, // Nucleus sampling
repetitionPenalty: 1.1, // Penalize repeats
repetitionContextSize: 20 // Window for penalty
)
```
### Prompt Caching / History Re-hydration
Restore chat from persisted history:
```swift
let history: [Chat.Message] = [
.system("You are helpful"),
.user("Hello"),
.assistant("Hi there!")
]
let session = ChatSession(
modelContainer,
history: history
)
// Continues from this point
```
## 5. Secondary Workflow: VLM Inference
### Image Input Types
```swift
// From URL (file or remote)
let image = UserInput.Image.url(fileURL)
// From CIImage
let image = UserInput.Image.ciImage(ciImage)
// From MLXArray directly
let image = UserInput.Image.array(mlxArray)
```
### Video Input
```swift
// From URL (file or remote)
let video = UserInput.Video.url(videoURL)
// From AVFoundation asset
let video = UserInput.Video.avAsset(avAsset)
// From pre-extracted frames
let video = UserInput.Video.frames(videoFrames)
let response = try await session.respond(
to: "What happens in this video?",
video: video
)
```
### Multiple Images
```swift
let images: [UserInput.Image] = [
.url(url1),
.url(url2)
]
let response = try await session.respond(
to: "Compare these two images",
images: images,
videos: []
)
```
### VLM-Specific Processing
```swift
let session = ChatSession(
modelContainer,
processing: UserInput.Processing(
resize: CGSize(width: 512, height: 512) // Resize images
)
)
```
## 6. Best Practices
### DO
```swift
// DO: Use ChatSession for multi-turn conversations
let session = ChatSession(modelContainer)
// DO: Use AsyncStream APIs (modern, Swift concurrency)
for try await chunk in session.streamResponse(to: prompt) { ... }
// DO: Check Task.isCancelled in long-running loops
for try await generation in stream {
if Task.isCancelled { break }
// process generation
}
// DO: Use ModelContainer.perform() for thread-safe access
await modelContainer.perform { context in
// Access model, tokenizer safely
let tokens = try context.tokenizer.applyChatTemplate(messages: messages)
return tokens
}
// DO: When breaking early from generation, use generateTask() to get a task handle
// This is the lower-level API used internally by ChatSession
let (stream, task) = generateTask(...) // Returns (AsyncStream, Task)
for await item in stream {
if shouldStop { break }
}
await task.value // Ensures KV cache cleanup before next generation
```
> `generateTask()` is defined in `Evaluate.swift`. Most users should use `ChatSession` which handles this internally.
### DON'T
```swift
// DON'T: Share MLXArray across tasks (not Sendable)
let array = MLXArray(...)
Task { array.sum() } // Wrong!
// DON'T: Use deprecated callback-based generation
// Old:
generate(input: input, parameters: params) { tokens in ... } // Deprecated
// New:
for await generation in try generate(input: input, parameters: params, context: context) { ... }
// DON'T: Use old perform(model, tokenizer) signature
// Old:
modelContainer.perform { model, tokenizer in ... } // Deprecated
// New:
modelContainer.perform { context in ... }
// DON'T: Forget to eval() MLXArrays before returning from perform()
await modelContainer.perform { context in
let result = context.model(input)
eval(result) // Required before returning
return result.item(Float.self)
}
```
### Thread Safety
- `ModelContainer` is `Sendable` and thread-safe
- `ChatSession` is NOT thread-safe (use from single task)
- `MLXArray` is NOT `Sendable` - don't pass across isolation boundaries
- Use `SendableBox` for transferring non-Sendable data in consuming contexts
### Memory Management
```swift
// For long contexts, use sliding window cache
let params = GenerateParameters(maxKVSize: 4096)
// For memory efficiency, use quantized cache
let params = GenerateParameters(kvBits: 4) // or 8
// Clear session cache when done
await session.clear()
```
## 7. Reference Links
For detailed documentation on specific topics, see:
| Reference | When to Use |
|-----------|-------------|
| [references/model-container.md](references/model-container.md) | Loading models, ModelContainer API, ModelConfiguration |
| [references/kv-cache.md](references/kv-cache.md) | Cache types, memory optimization, cache serialization |
| [references/concurrency.md](references/concurrency.md) | Thread safety, SerialAccessContainer, async patterns |
| [references/tool-calling.md](references/tool-calling.md) | Function calling, tool formats, ToolCallProcessor |
| [references/tokenizer-chat.md](references/tokenizer-chat.md) | Tokenizer, Chat.Message, EOS tokens |
| [references/supported-models.md](references/supported-models.md) | Model families, registries, model-specific config |
| [references/lora-adapters.md](references/lora-adapters.md) | LoRA/DoRA/QLoRA, loading adapters |
| [references/training.md](references/training.md) | LoRATrain API, fine-tuning |
| [references/embeddings.md](references/embeddings.md) | EmbeddingModel, pooling, use cases |
## 8. Deprecated Patterns Summary
Most common migrations (see individual reference files for topic-specific deprecations):
| If you see... | Use instead... |
|---------------|----------------|
| `generate(... didGenerate:)` callback | `generate(...) -> AsyncStream` |
| `perform { model, tokenizer in }` | `perform { context in }` |
| `TokenIterator(prompt: MLXArray)` | `TokenIterator(input: LMInput)` |
| `ModelRegistry` typealias | `LLMRegistry` or `VLMRegistry` |
| `createAttentionMask(h:cache:[KVCache]?)` | `createAttentionMask(h:cache:KVCache?)` |
Each reference file contains a "Deprecated Patterns" section with topic-specific migrations.
## 9. Automatic vs Manual Configuration
### Automatic Behaviors (NO developer action needed)
The framework handles these automatically:
| Feature | Details |
|---------|---------|
| **EOS token loading** | Loaded from `config.json` |
| **EOS token override** | Priority: `generation_config.json` > `config.json` > defaults |
| **EOS token merging** | All sources merged at generation time |
| **EOS token detection** | Stops generation automatically when EOS encountered |
| **Chat template application** | Applied automatically via `applyChatTemplate()` |
| **Tool call format detection** | Inferred from `model_type` in `config.json` |
| **Cache type selection** | Based on GenerateParameters (`maxKVSize`, `kvBits`) |
| **Tokenizer loading** | Loaded from `tokenizer.json` automatically |
| **Model weights loading** | Downloaded and loaded from HuggingFace |
### Optional Configuration (Developer MAY configure)
| Feature | When to Configure |
|---------|-------------------|
| `extraEOSTokens` | Only if model has unlisted stop tokens |
| `toolCallFormat` | Only to override auto-detection |
| `maxKVSize` | To enable sliding window cache |
| `kvBits` | To enable quantized cache (4 or 8 bit) |
| `maxTokens` | To limit output length |
用 gh 命令列工具檢視 GitHub 上的 PR 檢查、工作流執行與 API 查詢的技能。
聚合 16 個搜尋引擎、無需 API Key 的檢索技能。
用命令列直接列出、配置、授權並呼叫 MCP 服務與工具。
生成有效的 Mermaid 圖表,如流程圖、時序圖、思維導圖、ER 圖、使用者旅程等。
用受管 OAuth 訪問 YouTube Data API,檢索影片並管理頻道內容。
透過受管的 OAuth 連線訪問 GitHub REST API。
覆蓋規劃、實現、驗證與測試的編碼工作流技能。
整理 Docker 常用命令與容器工作流的技能。
資料月份:2026-09 · 下載/星標/安裝數聚合自公開技能註冊庫(ClawHub、SkillHub),按月更新。口徑說明見資料方法。