# MarkBase 功能补充路线图 ## 目标定位 **MarkBase 定位**: - Apple Silicon 专属高性能推理引擎 - Swift 生态系统集成 - 教育研究 + 原型开发平台 - iOS/macOS 应用后端集成 **不竞争**: - 生产级多GPU服务(vLLM领域) - 跨平台通用部署(llama.cpp领域) - 一键易用工具(ollama领域) --- ## Phase 1: 核心功能完善(必需) ### 1.1 Tokenizer 集成 **目标**:支持文本输入,无需手动token ID **实现方案**: ```swift // Tokenizer protocols public protocol Tokenizer { func encode(text: String) -> [Int] func decode(tokens: [Int]) -> String var vocabSize: Int { get } } // SentencePiece tokenizer (Gemma使用) public final class SentencePieceTokenizer: Tokenizer { private let model: SentencePieceModel private let vocab: [String: Int] private let reverseVocab: [Int: String] public init(modelPath: String) throws { // Load .model or .tokenizer.json } public func encode(text: String) -> [Int] { // BPE encoding algorithm } public func decode(tokens: [Int]) -> String { // Token to text conversion } } ``` **文件结构**: ``` Sources/G12B/Tokenizer/ ├── Tokenizer.swift (protocol) ├── SentencePieceTokenizer.swift ├── BPETokenizer.swift └── TokenizerLoader.swift ``` **依赖**: - 无外部依赖(纯Swift实现) - 或集成 `swift-sentencepiece`(轻量库) **时间估算**:2-3天 - Day 1: 协议定义 + SentencePiece解析 - Day 2: Encode/decode实现 + 测试 - Day 3: Gemma tokenizer适配 + 集成 **测试验证**: ```swift let tokenizer = try SentencePieceTokenizer(modelPath: modelDir) let tokens = tokenizer.encode("Hello world") let text = tokenizer.decode(tokens) XCTAssertEqual(text, "Hello world") ``` --- ### 1.2 流式输出 **目标**:Token-by-token生成,实时显示 **实现方案**: ```swift public final class StreamingGenerator { private let model: E4BModel private let tokenizer: Tokenizer private let engine: MarkBaseEngine public func generate( prompt: String, maxTokens: Int, temperature: Float = 1.0 ) -> AsyncStream { // AsyncStream for token-by-token output return AsyncStream { continuation in // Generation loop for token in generatedTokens { let text = tokenizer.decode([token]) continuation.yield(text) } continuation.finish() } } } // Usage let generator = StreamingGenerator(model: model, tokenizer: tokenizer) for await tokenText in generator.generate(prompt: "Hello", maxTokens: 100) { print(tokenText) // Real-time output } ``` **技术要点**: - 使用 Swift `AsyncStream`(异步流) - 每生成一个token立即输出 - 支持异步取消 **文件结构**: ``` Sources/G12B/Generator/ ├── StreamingGenerator.swift ├── GenerationConfig.swift ``` **时间估算**:1天 --- ### 1.3 采样策略 **目标**:支持Top-k、Top-p、Temperature等采样 **实现方案**: ```swift public struct SamplingConfig { public let temperature: Float // 0.0-2.0 public let topK: Int? // Top-k sampling public let topP: Float? // Top-p (nucleus) sampling public let repetitionPenalty: Float? public init(temperature: Float = 1.0, topK: Int? = nil, topP: Float? = nil) { self.temperature = temperature self.topK = topK self.topP = topP } } public final class Sampler { public func sample(logits: [Float], config: SamplingConfig) -> Int { // Apply temperature var probs = softmax(logits.map { $0 / config.temperature }) // Top-k filtering if let k = config.topK { probs = applyTopK(probs, k: k) } // Top-p filtering if let p = config.topP { probs = applyTopP(probs, p: p) } // Random sampling return randomSample(probs) } private func softmax(_ values: [Float]) -> [Float] private func applyTopK(_ probs: [Float], k: Int) -> [Float] private func applyTopP(_ probs: [Float], p: Float) -> [Float] } ``` **文件结构**: ``` Sources/G12B/Sampling/ ├── Sampler.swift ├── SamplingConfig.swift ├── Softmax.swift (Metal kernel) ``` **时间估算**:1-2天 - Day 1: 采样算法实现 + Softmax Metal kernel - Day 2: 测试 + 验证生成质量 --- ## Phase 2: 生产功能增强(重要) ### 2.1 HTTP API服务 **目标**:提供REST API endpoint **实现方案**: ```swift // 使用 Vapor 或 Hummingbird (轻量) import Hummingbird public final class InferenceAPI { private let generator: StreamingGenerator public func startServer(port: Int = 8080) throws { let app = HBApplication(port: port) // POST /generate app.router.post("/generate") { request, context in let body = try request.body.decode(GenerateRequest.self) let result = try generator.generate( prompt: body.prompt, maxTokens: body.maxTokens ?? 100, config: body.config ?? SamplingConfig() ) return GenerateResponse(tokens: result) } // POST /stream (WebSocket) app.router.post("/stream") { ... } try app.start() } } struct GenerateRequest: Codable { let prompt: String let maxTokens: Int? let config: SamplingConfig? } struct GenerateResponse: Codable { let tokens: [Int] let text: String } ``` **API设计**: - `POST /generate` - 单次生成 - `POST /stream` - 流式生成(WebSocket) - `GET /models` - 模型列表 - `GET /health` - 健康检查 **依赖选择**: - **Hummingbird**(推荐):轻量、Swift原生 - **Vapor**:功能完整、但较重 **文件结构**: ``` Sources/G12B/API/ ├── InferenceAPI.swift ├── APIModels.swift ├── Routes.swift ``` **时间估算**:3-4天 - Day 1: API框架搭建 + 基础endpoint - Day 2: 请求处理 + 错误处理 - Day 3: WebSocket流式输出 - Day 4: 测试 + 文档 --- ### 2.2 并发支持 **目标**:多request并发处理 **实现方案**: ```swift public final class ConcurrentGenerator { private let model: E4BModel private let tokenizer: Tokenizer private let engine: MarkBaseEngine private let queue: DispatchQueue // Batch processing with KV cache sharing public func generateBatch( prompts: [String], maxTokens: Int ) async throws -> [String] { return try await withThrowingTaskGroup(of: String.self) { group in for prompt in prompts { group.addTask { try await generateSingle(prompt: prompt, maxTokens: maxTokens) } } var results: [String] = [] for try await result in group { results.append(result) } return results } } } ``` **技术要点**: - Swift async/await并发 - DispatchQueue调度 - 批处理KV cache优化 **文件结构**: ``` Sources/G12B/Concurrent/ ├── ConcurrentGenerator.swift ├── RequestQueue.swift ``` **时间估算**:2-3天 --- ## Phase 3: 生态完善(可选) ### 3.1 模型自动下载 **目标**:自动从HuggingFace下载模型 ```swift public final class ModelDownloader { public func download( modelId: String, cacheDir: String = "~/.cache/huggingface" ) async throws -> String { // Download from HuggingFace Hub // Use huggingface-cli or custom implementation } } ``` **时间估算**:2-3天 --- ### 3.2 iOS/macOS应用集成 **目标**:提供App框架模板 ```swift // SwiftUI integration public struct ChatView: View { @StateObject private var chatModel = ChatModel() var body: some View { VStack { // Chat UI } } } public final class ChatModel: ObservableObject { private let generator: StreamingGenerator @Published var messages: [Message] = [] } ``` **时间估算**:5-7天 --- ## 实施优先级 ### 第一阶段(必需,4-6天) | 功能 | 时间 | 依赖 | 优先级 | |------|------|------|--------| | Tokenizer集成 | 2-3天 | 无 | ⭐⭐⭐⭐⭐ | | 流式输出 | 1天 | Tokenizer | ⭐⭐⭐⭐⭐ | | 采样策略 | 1-2天 | 无 | ⭐⭐⭐⭐ | **完成后效果**: - ✅ 可直接输入文本(无需手动token) - ✅ 实时流式输出 - ✅ 灵活采样策略 - ✅ 完整文本生成体验 --- ### 第二阶段(重要,5-7天) | 功能 | 时间 | 依赖 | 优先级 | |------|------|------|--------| | HTTP API | 3-4天 | Tokenizer, 采样 | ⭐⭐⭐⭐ | | 并发支持 | 2-3天 | API | ⭐⭐⭐ | **完成后效果**: - ✅ REST API可用 - ✅ 多request并发 - ✅ 服务级部署 --- ### 第三阶段(可选,7-10天) | 功能 | 时间 | 依赖 | 优先级 | |------|------|------|--------| | 模型自动下载 | 2-3天 | 无 | ⭐⭐ | | iOS/macOS App模板 | 5-7天 | API | ⭐⭐ | --- ## 兼容性设计 ### E4B和12B统一接口 ```swift // Unified generation interface public protocol TextGenerator { func generate( prompt: String, maxTokens: Int, config: SamplingConfig ) throws -> String func streamGenerate( prompt: String, maxTokens: Int, config: SamplingConfig ) -> AsyncStream } // E4B和12B都实现此协议 extension E4BModel: TextGenerator { ... } extension MultimodalModel: TextGenerator { ... } ``` **设计原则**: - E4B和12B共享相同接口 - Tokenizer统一加载 - 采样策略通用 - API统一endpoint --- ## 技术栈选择 ### 依赖库(推荐) | 功能 | 推荐库 | 原因 | |------|--------|------| | **HTTP框架** | Hummingbird | 轻量、Swift原生 | | **Tokenizer** | 纯Swift实现 | 无外部依赖 | | **异步并发** | Swift AsyncStream | 语言原生 | | **JSON处理** | Codable | 语言原生 | **避免依赖**: - ❌ Vapor(太重) - ❌ 外部tokenizer库(Swift生态少) - ❌ Python互操作(破坏纯Swift) --- ## 测试策略 ### 每阶段测试 **Phase 1测试**: ```swift // Tokenizer测试 func testTokenizer() throws { let tokenizer = try SentencePieceTokenizer(modelPath: modelDir) let tokens = tokenizer.encode("Hello world") XCTAssertEqual(tokens.count, > 0) let decoded = tokenizer.decode(tokens) XCTAssertEqual(decoded, "Hello world") } // 流式输出测试 func testStreaming() async throws { let generator = StreamingGenerator(model: model, tokenizer: tokenizer) var tokens: [String] = [] for await token in generator.generate(prompt: "Test", maxTokens: 10) { tokens.append(token) } XCTAssertEqual(tokens.count, 10) } // 采样测试 func testSampling() throws { let sampler = Sampler() let config = SamplingConfig(temperature: 0.8, topK: 50) let logits = model.forward(tokenId: 0, position: 0) let token = sampler.sample(logits: logits, config: config) XCTAssertGreaterThanOrEqual(token, 0) } ``` --- ## 文档更新 ### 每阶段更新文档 **Phase 1完成后**: - README.md更新(Tokenizer + Streaming示例) - API_REFERENCE.md新增 - QUICK_START.md快速指南 **Phase 2完成后**: - API_SERVER.md(HTTP endpoint文档) - DEPLOYMENT.md(部署指南) --- ## 实施建议 ### 方案A:快速原型(推荐) **时间**:4-6天(Phase 1) **目标**: - ✅ Tokenizer集成 - ✅ 流式输出 - ✅ 采样策略 **效果**: - 完整文本生成体验 - 媒体演示可用 - 教育价值最大化 --- ### 方案B:生产级(可选) **时间**:9-13天(Phase 1+2) **目标**: - ✅ Phase 1功能 - ✅ HTTP API - ✅ 并发支持 **效果**: - 服务级部署 - 多用户访问 - API可用 --- ### 方案C:完整生态(不推荐) **时间**:16-23天(Phase 1+2+3) **投入产出低**: - 不竞争ollama易用性 - 不竞争vLLM生产级 - 定位错位 --- ## 关键决策 **需要回答**: 1. **目标用户是谁?** - Swift开发者?研究者?生产用户? 2. **投入预算?** - 4-6天?9-13天?16+天? 3. **定位策略?** - 教育研究工具? - iOS/macOS应用后端? - API服务提供者? --- ## 我的推荐 **推荐方案A(快速原型)** **理由**: 1. **投入产出最优** - 4-6天投入 - 完整文本生成体验 - 教育演示价值最大化 2. **定位正确** - 教育研究工具 - Swift开发者友好 - Apple Silicon专属 3. **避免竞争** - 不与ollama竞争易用性 - 不与vLLM竞争生产级 - 保持差异化优势 **下一步行动**: - 用户确认方案选择 - 开始Phase 1实施(Tokenizer + Streaming + Sampling) --- ## 总结 **MarkBase核心竞争力**: - ✅ Apple Silicon性能优化 - ✅ 纯Swift原生实现 - ✅ 教育研究价值 - ✅ 完全定制能力 **功能缺口**: - ❌ Tokenizer(必需) - ❌ 流式输出(必需) - ❌ 采样策略(必需) - ⚠️ API服务(可选) **最优策略**: - Phase 1实施(4-6天) - 定位为教育/研究工具 - 保持Swift生态特色 - 不竞争生产市场 是否开始Phase 1实施?