標籤: Qwen 3.6

  • 270 億參數上 iPhone 的實戰路線

    270 億參數上 iPhone 的實戰路線

    📌 本文重點

    • 27B 大模型壓縮後可在手機端側實用
    • 量化 +剪枝 +蒸餾是端側部署核心組合
    • 善用 NPU/GPU 與 RAG/Agent 架構提升體驗

    在端側塞進 Qwen 3.6-27B 這種體量的模型,直接解決了三個痛點

    1. 隱私 & 合規:聊天、RAG 查文件、簡單 Agent 全在本機,不丟到雲端。
    2. 互動延遲:減少網路 RTT,短指令(改句子、補程式)能接近即時回應。
    3. 成本 & 擴展:不用為每個活躍使用者準備一個雲端 GPU,端側模型成為主力推理,引流雲端模型解決長上下文或高難任務。

    PrismML 把 Qwen 3.6-27B 壓到能在 iPhone 17 Pro 上跑,給了我們一個清楚訊號:27B 級模型上手機是可行路線,但你要整套壓縮 + runtime + 系統調優一起做


    重點說明:端側大模型的幾個關鍵技術

    1. 量化:從 16bit 壓到 4bit / 2bit

    目的:壓縮權重體積 + 減輕記憶體頻寬壓力

    • 粗估:
    • FP16:27B × 2 bytes ≈ 54 GB(純權重就爆)
    • 4bit:27B × 0.5 bytes ≈ 13.5 GB
    • 2bit:27B × 0.25 bytes ≈ 6.75 GB

    💡 關鍵: 把 27B 權重從 54GB 壓到約 7–14GB,是端側部署能否落地的基礎門檻

    • 實務上常用 mixed-precision
    • attention / embedding 保留 8bit 或 16bit
    • MLP 可用 4bit 或 2bit(配合 group-wise scaling)
    • 在 iOS 端常見兩種路線:
    • GGUF + llama.cpp:用 Q4_K_M / Q3_K_M 這類 profile
    • Core ML / MLC:用 symmetric int4 / int8,用 LUT 把量化常數 bake 進權重

    對專案的好處:

    • 同一隻 app 可以提供 小模型 + 壓縮大模型 的雙模式:日常用 7B,開「專業模式」時啟動 27B(但速度變慢 + 發熱)。

    2. 剪枝與低秩分解:不只變小,還要能跑快

    量化只壓體積,不一定壓算力;要在功耗有限的手機跑得動,需要再用:

    1. 結構化剪枝(structured pruning)
    2. 砍掉整個 head、channel 或 FFN neuron。
    3. 例如把 32 heads 剪到 24 heads,或把 FFN hidden dim 從 8k 降到 6k。
    4. 這會直接減少 MACs,對 NPU / GPU 友善。
    5. 低秩分解(LoRA / SVD 分解 FFN 權重)
    6. 把大矩陣 (W \in \mathbb{R}^{d \times d}) 分成 (U \in \mathbb{R}^{d \times r}, V \in \mathbb{R}^{r \times d}),r ≪ d
    7. 搭配蒸餾可以維持合理能力。

    PrismML 類型的方案多半是 多階段:量化 + 剪枝 + 蒸餾 + runtime 特化 一起做,才有可能把 27B 折成 iPhone 等級的 latency。

    3. KV Cache / 推理圖優化:token/s 的決勝點

    端側 LLM 的痛點不是 model load,而是 持續推理的 token/s 與發熱

    關鍵是:

    • KV Cache 緊縮
    • 精度壓到 8bit/4bit(與權重量化分開考慮)。
    • 善用 sliding window / attention sink,減少長對話時的 KV 佔用。
    • 推理圖優化(graph optimization)
    • 透過 MLC / Core ML / 自研 runtime 把整段 transformer block fuse 成 1–2 個大 kernel。
    • 減少 CPU ↔ NPU ↔ GPU 之間的 context switch。

    效果:在 iPhone 17 Pro 這種等級裝置,27B 壓縮到 4bit + 優化 graph,合理預期 5–10 tok/s 左右(看溫控),可以應付聊天、簡單 RAG,但不是寫 3k 行程式碼那種長輸出場景。

    💡 關鍵: 端側大模型的體感速度主要由 token/s 決定,5–10 tok/s 大致只適合短回覆與簡單任務

    4. 善用手機 NPU / GPU:不是「丟上去就快」

    iOS 上大致有三條路:

    1. Core ML + ANE(NPU)
    2. 最省電,但要配合 Core ML 支援的 op / dtype,需要前置轉換。
    3. Metal / MLC
    4. 走 GPU / CPU + 少量 NPU,對自訂 kernel 比較自由。
    5. llama.cpp(Metal 後端)
    6. 直接吃 GGUF,開 Metal 加速;部分 op 仍在 CPU。

    實務上可以採用 混合策略:embedding / 前幾層在 NPU,後面在 GPU / CPU,平衡記憶體與溫度。


    實作範例:在 iOS 上做聊天 / RAG / Agent 的架構

    下面給一個「實際可落地」的 27B 壓縮部署思路,用 pseudo code 表示。

    1. 推理框架選型與模型準備

    方案 A:llama.cpp + GGUF(開發週期短)

    1. 先把 Qwen 3.6-27B 轉成 GGUF 並量化(在桌機完成):
    python convert_qwen_to_gguf.py \
      --model qwen-3.6-27b \
      --out qwen-3.6-27b-q4_k_m.gguf
    
    ./quantize \
      qwen-3.6-27b-q4_k_m.gguf \
      qwen-3.6-27b-q4_k_m.gguf \
      Q4_K_M
    
    1. iOS 使用 llama.cpp Swift / C API:
    let params = gpt_params_default()
    params.n_ctx = 4096
    params.n_gpu_layers = 20   // 前 20 層走 Metal
    
    let ctx = llama_init_from_file("qwen-3.6-27b-q4_k_m.gguf", params)
    
    func infer(prompt: String) -> String {
        llama_reset(ctx)
        llama_eval_prompt(ctx, prompt)
        var output = ""
        while !shouldStop(output) {
            let token = llama_eval_next(ctx)
            output += tokenizer.decode(token)
        }
        return output
    }
    

    注意:n_gpu_layers 設太高,會爆 VRAM / 發熱;設太低,會被 CPU 拖死。實測需要在 8–24 之間找平衡。

    方案 B:MLC LLM + Metal(更深度優化)

    • 透過 MLC 工具鏈把 Qwen 3.6-27B 壓成 int4 + fused kernels,生成 iOS 專用模型包:
    mlc_llm convert qwen-3.6-27b \
      --quantization q4f16_0 \
      --target iphone
    
    mlc_llm build ios qwen-3.6-27b-q4f16_0
    

    iOS 端呼叫:

    let engine = MLCChatEngine(model: "qwen-27b-q4f16_0")
    
    engine.generate(
      prompt: userPrompt,
      maxTokens: 512,
      temperature: 0.7,
      streamHandler: { token in
        appendToUI(token)
      }
    )
    

    實務建議:若不是要深度客製 runtime,MLC 會比自己改 llama.cpp 更好拿穩定 fps 和電源管理

    2. RAG:本機嵌入 + 文件切片

    架構:

    • 輕量 embedding 模型(如 384–768 dim)放端側
    • 文本切 chunk(512–1024 tokens),建立本地向量索引。
    • 查詢時在端側 embed + ANN 搜索 + top-k context 拼回 prompt,再丟給 27B 生成。

    簡易 Swift 流程(以 Core ML embedding 模型為例):

    // 1. 建立索引(啟動或背景時)
    for chunk in documentChunks {
        let emb = embeddingModel.encode(text: chunk.text) // [Float]
        annIndex.add(vector: emb, id: chunk.id)
    }
    
    // 2. 查詢時
    func ragAnswer(query: String) -> String {
        let qEmb = embeddingModel.encode(text: query)
        let topK = annIndex.search(query: qEmb, k: 4)
        let context = topK.map { $0.text }.joined(separator: "\
    ---\
    ")
    
        let prompt = """
    你是一個助理。以下是知識庫內容:
    \(context)
    
    問題:\(query)
    請根據知識庫回答,若沒有明確答案就說不知道。
    """
        return infer(prompt: prompt)
    }
    

    好處

    • 敏感文件不離開手機;
    • 即使 27B 很慢,RAG 因為 context 精準,需要生成的 token 也變少

    3. 簡單 Agent:有限循環 + 工具調用

    在端側做 Agent 不要太貪心,建議:

    • 限制 max steps(例如 4–6 步)。
    • 工具呼叫只做本機能力:檔案讀寫、日曆、藍牙裝置等。

    簡化 pseudo code:

    struct ToolCall { let name: String; let args: [String: Any] }
    
    func runAgent(task: String) {
        var state = ""
        for step in 0..<6 {
            let prompt = buildAgentPrompt(task: task, state: state)
            let output = infer(prompt: prompt)
    
            if let tool = parseToolCall(output) {
                let result = executeTool(tool)
                state += "\
    [tool-result]\
    " + result
            } else {
                renderFinal(output)
                break
            }
        }
    }
    

    這種架構在 27B 上 iPhone 實務可行,但要注意:token/s 慢 → 每一輪推理越短越好,prompt 盡量模板化、少廢話。


    建議與注意事項:坑在哪、怎麼踩得比較輕

    1. 記憶體與冷啟動

    • iPhone 17 Pro 類級別裝置,27B 4bit 純權重就十幾 GB,實務上需:
    • 模型分片 / 分層載入
      • 常駐 7B 小模型;
      • 27B 大模型在「高需求模式」才 mmap 載入部分層(如後 12 層)。
    • 或採 Mixture-of-Experts(MoE) 類方案,如 GLM 5.2 + Flash MoE,那類模型在 Mac M5 上可跑 2–2.8 tok/s,給端側設計方向參考:不是所有 layer 都要 full dense
    • 冷啟動:
    • 首次 load 27B 量化模型,可能 3–10 秒,一定要做 loading UI + 延遲初始化(app 啟動時先載小模型,使用者開「專業模式」才載大模型)。

    💡 關鍵: 3–10 秒的冷啟動延遲是端側大模型的 UX 關鍵,必須用分層載入與明確 UI 掩護

    2. 電量與發熱

    • 連續推理 1–2 分鐘,大模型會把 SoC 拉到 TDP 上限,掉頻後 token/s 會明顯下降。
    • 實作上建議:
    • 限制 max_tokens,避免長篇輸出。
    • 使用 溫度監控(ThermalState,高溫時降速:
    if ProcessInfo.processInfo.thermalState == .serious {
        params.n_threads = max(2, params.n_threads / 2)
    }
    

    3. 隱私與合規

    • Ce 合規角度,端側推理 + 本地 RAG 是加分項,但要注意:
    • 日誌、錯誤回報不得包含原文檔內容。
    • 若有雲端 fallback,要明確 UI 提示「此問題將送出至伺服器」。

    4. 測試方法與性能預估

    建議自建簡單基準腳本,統計:

    • 冷啟動時間(model load 完到第一 token)
    • token/s(前 50 tokens、整段平均)
    • 電池掉電率與機身溫度(5 分鐘連續推理)

    例:用 llama.cpp CLI 在開發機 / TestFlight 內部版測一次:

    ./main -m qwen-27b-q4_k_m.gguf \
      -p "Hello" -n 256 -s 42 --timings
    

    官方輸出會給:

    • prompt eval time / token
    • generation eval time / token

    再用這些數據估算:

    • 聊天:平均 50–100 tokens → 是否能在 3–5 秒內完成?
    • RAG:查詢 + 150 tokens → 整體延遲能否低於 10 秒?

    結論:端側 27B 的實際策略

    對多數 iOS 專案,建議的 可實作路線 是:

    1. 產品層:
    2. 7B–8B 模型 作為主力。
    3. 提供「離線高精度模式」載入壓縮 27B,給重度用戶 & 高價方案。
    4. 技術層:
    5. 量化採 4bit mixed-precision,配合剪枝 + 蒸餾。
    6. 選擇 MLC / llama.cpp Metal 後端,不要自幹 runtime,除非是公司核心技術。
    7. 系統層:
    8. 做好 分層部署 + 延遲載入 + 熱管理
    9. 嵌入模型 + RAG 索引用小模型處理,27B 只負責最終生成。

    這樣設計,你可以合理地把「看起來誇張的 27B」塞進 iPhone 裡,並且在聊天、RAG、輕量 Agent 這幾個場景拿到實際可用的體驗。真正的難點不只在模型壓縮,而是在整條端側推理鏈的工程化

    🚀 你現在可以做的事

    • 在開發機上用 llama.cpp 或 MLC 先跑一版 Qwen 3.6-27B 4bit,量測 token/s 與冷啟動時間
    • 選定一個 7B 模型做端側 RAG PoC,實作本地嵌入與向量索引流程
    • 規劃產品中的「專業模式」或「離線高精度模式」,設計 7B / 27B 雙模型切換與載入策略
  • 用 Deer-Flow 自建長跑 AI SuperAgent

    用 Deer-Flow 自建長跑 AI SuperAgent

    📌 本文重點

    • Deer-Flow 把長時間任務拆成可控模組
    • 透過記憶體與子代理協作支援長期、多階段任務
    • 搭配沙盒與工具調用,可快速做出實用自動化 Pipeline

    只要先把任務切成模組、再讓 Agent 自己排程與記憶,Deer-Flow 能幫你把「要跑幾小時」的專案變成一條可控又可復用的自動化流程。

    專案連結:bytedance/deer-flow


    核心功能:把「長時間任務」拆成可控模組

    這一節先講概念,但每個小節都會對應到你可以馬上去做的事。


    1. 任務調度:讓 Agent 分段跑,而不是一口氣硬撐

    Deer-Flow 的定位是「long-horizon SuperAgent harness」,核心就是任務調度(scheduler):

    • 把大任務拆成多個 stage(例如:資料收集 → 清洗 → 分析 → 報告)
    • 每個 stage 由一個或多個子代理(subagents)負責
    • 調度器會決定:
    • 什麼時候喚醒哪個子代理
    • 什麼時候暫停、重試、或改走另一條路徑

    你可以把它想像成「AI 版本的 Airflow + 任務導向的聊天界面」。

    💡 關鍵: 把長任務拆成多個 stage,讓 scheduler 分段調度 subagents,可以大幅降低單次失敗風險並提升整體可控性。

    你可以馬上做的事:

    1. 打開專案的 examples/ 資料夾,看官方提供的 flow 定義(多半是 YAML 或 Python pipeline)。
    2. 想一個你日常會重複做的 3–4 步驟任務(例如:抓資料 → 存 DB → 寫 summary),在筆記上先畫出 3–4 個方框,對應到未來的 stage 名稱。

    2. 記憶體管理:讓 Agent 記得「之前做過什麼」

    長時間任務的難點,不是算力,而是「上下文會爆掉」。

    Deer-Flow 幫你管的是:

    • 短期記憶(working memory:某個子任務當下需要的上下文
    • 長期記憶(long-term memory:歷史任務紀錄、重要結果、被標記的關鍵中間產物
    • 記憶裁剪:把不重要的對話 / log 丟掉,只保留後續階段會用到的東西

    這樣一來,你可以讓同一個 Agent:

    • 早上先跑一輪資料爬取
    • 下午再接續早上的結果繼續清洗與分析

    你可以馬上做的事:

    1. 在官方 demo 裡,找到記憶相關設定(通常會指定儲存路徑或使用向量資料庫)。
    2. 先用預設的本地檔案儲存方式,觀察它怎麼把多輪任務寫進 log / memory,了解自己之後可以在哪裡接入自己的資料庫。

    3. 子代理協作 + 工具調用:像組一隊虛擬實習生

    Deer-Flow 支援多個 subagents,每個都可以:

    • 使用不同的 LLM(例如:一個負責寫程式,一個負責資料分析)
    • 綁不同的工具(HTTP、資料庫、內部 API
    • 透過 message gateway 互相傳遞任務與結果

    同時,它內建「工具調用」的框架:

    • LLM 輸出「要用哪個工具 + 參數」
    • Deer-Flow 幫你實際執行(例如發 HTTP 請求、查 DB
    • 把結果再丟回 LLM 繼續推理

    你可以馬上做的事:

    1. toolsskills 相關的範例中,找到 HTTP request 或資料庫工具的例子。
    2. 把它改成呼叫你公司內部一個可公開測試的 API(例如:/health/status),確認整條「LLM 決定 → 工具執行 → LLM 使用結果」流程可用。

    4. 沙盒執行程式碼:讓 Agent 先在安全盒子裡試錯

    Deer-Flow 特別強調 sandboxes

    • Agent 產生或修改程式碼時,不會直接在主機上執行
    • 而是丟到隔離環境(容器 / sandbox 子進程)裡跑
    • 出現錯誤時,log 會被收集回來給 LLM 參考,做下一輪修正

    這一點非常適合以下情境:

    • 讓 Agent 自動寫爬蟲、清洗腳本
    • 讓 Agent 幫你布署一個小型服務(只在 sandbox 測試通過後才進正式環境)

    你可以馬上做的事:

    1. 在官方 demo 裡跑一個「code sandbox」相關示例,看它怎麼把程式碼丟到沙盒執行。
    2. sandbox 內部要執行的腳本換成你平常會用的簡單任務,例如:讀取一個 CSV,輸出 JSON

    適合誰用:3 個具體場景


    場景 1:長時間資料爬取與整理

    典型流程:

    1. Agent A:負責定義爬取策略(網站列表、節奏控制)
    2. Agent B:實際發 HTTP 請求、解析 HTML / API
    3. Agent C:清洗資料、存進資料庫
    4. Agent D:最後產出摘要報告(例如每天一份 Markdown 摘要)

    Deer-Flow 的用法:

    • 每個 Agent 是一個 subagent
    • 任務調度器負責安排「今天要爬哪些」、「昨天失敗的要重試」
    • 記憶體管理幫你記住爬過哪些 URL,避免重複

    行動建議:

    • 選一個你每天都會看的公開資料來源(例如某政府開放資料 API),用 Deer-Flow 做一個「每日抓取 + insert DB + 產出報表」的 pipeline

    場景 2:從需求到部署的自動化小專案

    你可以把它當成一個「AI junior developer」:

    1. Agent 讀取你的需求(功能描述、預期輸入輸出)
    2. sandbox 裡生成與跑單元測試
    3. 修正錯誤
    4. 最後產出可部署的腳本或 Dockerfile

    搭配本地 LLM(例如 Qwen 3.6 27B,搭配 MTP 加速,參考:這篇 Reddit 分享),你可以完全在內網完成這一串。

    💡 關鍵: 搭配 Qwen 3.6 27BMTP,有實務經驗分享可達到推理速度約「2.5×」提升,使本地端長任務也具備實用性。

    行動建議:

    • 挑一個小腳本需求,例如:
    • 定期掃描資料夾,壓縮過期檔案
    • 監控某個 API latency,超標就寄信
    • 讓 Deer-Flow 的 Agent 在 sandbox 中生成並測試這個腳本,再由你審核後部署。

    場景 3:定期報表生成(營運、行銷、IT 系統狀態)

    想像每週要手工做的:

    • 把資料庫中的數據抓出來
    • 做一些聚合 / 分析
    • 輸出 PowerPointMarkdown 報告

    Deer-Flow 可以這樣組:

    1. 工具:資料庫查詢工具(連到你的 PostgreSQL / MySQL
    2. Agent:
    3. 一個負責定義查詢與聚合邏輯
    4. 一個負責把結果轉成自然語言與圖表描述
    5. 調度:排成 cron-like 任務,每週執行一次

    行動建議:

    • 從一個最簡單的報表開始,例如「每週新用戶數」,用 Deer-Flow 將流程自動化,先做到:
    • Agent 查 DB → 產出一份 Markdown 報告存檔 → 你手動審閱

    怎麼開始:最小可行 Pipeline

    下面是一條「週末就能跑起來」的最簡路線。


    步驟 1:環境與安裝

    1. 準備一台有 Python 3.10+ 的機器(本機或雲端皆可)。
    2. 進入命令列:
    git clone https://github.com/bytedance/deer-flow.git
    cd deer-flow
    python -m venv .venv
    source .venv/bin/activate  # Windows 用 .venv\Scripts\activate
    pip install -r requirements.txt
    
    1. 確認可以跑官方 demo(通常在 examples/):
    python examples/basic_flow.py
    

    目標:先看到一個完整任務從「開始 → 調用 LLM → 調用工具 → 結束」的 log


    步驟 2:接上一個開源 LLM(本機或雲端)

    你有兩條路:

    • 本機模型:用 llama.cppOllamaQwen 3.6 之類的模型
    • 雲端 API:用 OpenAIAnthropic 或其他 OpenAI-compatible 服務

    OpenAI 介面為例,Deer-Flow 通常會在設定檔或程式中要求:

    llm_config = {
        "endpoint": "https://your-openai-compatible-endpoint/v1",
        "api_key": "YOUR_KEY",
        "model": "qwen-3.6-32b-instruct"  # 或其他你有的模型名
    }
    

    行動建議:

    • 如果你已經有在用本地模型,直接把你熟悉的 OpenAI-compatible endpoint(例如 vLLM、自建 server)填進來,確認 Deer-Flow 可以正常發出 completion / chat 請求。

    步驟 3:串一個最簡單的工具(HTTP / 資料庫 / 內部 API)

    HTTP 工具為例,你可以新增一個 tool

    from deer_flow.tools import register_tool
    import requests
    
    @register_tool("get_status")
    def get_status(url: str):
        resp = requests.get(url, timeout=10)
        return {"status_code": resp.status_code, "body": resp.text[:1000]}
    

    然後在 Agent 的工具清單中加入 get_status,讓 LLM 可以呼叫它:

    • Prompt 裡描述:「有一個工具 get_status(url) 用來檢查服務狀態」
    • 將你的內部 /health API 當成第一個測試目標

    行動建議:

    • 先讓 Agent 自己決定:
    • 什麼時候要呼叫 get_status
    • 呼叫後如何解讀結果(例如:狀態碼非 200 就記錄成 incident

    週末練習腳本:從官方 demo 改成你的業務任務

    把以上步驟變成一個可執行的「週末計畫」:

    1. 跑起官方 demo
    2. 目標:看到完整的 log 與結果
    3. 換成你的 LLM
    4. 本地 Qwen / 雲端 API 任一種
    5. 串一個工具
    6. HTTP 或資料庫擇一
    7. 改寫 flow
    8. 讓 Agent 幫你跑一個真實業務任務,例如:
      • 每日抓一個內部 API 的統計數據
      • 存到一個簡單的 SQLite / CSV
      • 產出一行 summary

    做到這裡,你就已經擁有一個「專門幫你跑重複工作幾小時」的長跑 AI SuperAgent 雛型,接下來再慢慢加 stage、加子代理,就能讓它接手越來越多的例行任務。

    💡 關鍵: 先完成最小可行 pipeline,再逐步增加 stage 和工具,可以在風險可控下循序擴張自動化範圍。


    🚀 你現在可以做的事

    • 到 GitHub 下載並跑一次 bytedance/deer-flow 的官方 examples/basic_flow.py
    • 挑一個你日常 3–4 步驟的例行任務,畫出對應 stage,準備改寫成 Deer-Flow pipeline
    • 接上你的第一個實際工具(例如內部 /health API),驗證「LLM 決策 → 工具執行 → LLM 消化結果」這條鏈路在你環境中可用