星期一, 5月 11, 2026

# 小米 15 本地 AI 教學:Llama.cpp + Adreno 830 GPU 加速

 # 小米 15 本地 AI 教學:Llama.cpp + Adreno 830 GPU 加速


## 硬體資訊

- 手機:小米 15 (Xiaomi 15)

- 處理器:Snapdragon 8 Elite

- GPU:Adreno 830

- 最大 GPU 記憶體:~1GB

- 系統:Android + Termux


---


## 第一部分:安裝 Termux 與環境設定


### 1. 安裝 Termux

從 **F-Droid**(不要用 Google Play)下載 Termux:

```

https://f-droid.org/packages/com.termux/

```


### 2. 更新與安裝依賴

```bash

pkg update && pkg upgrade

pkg install git cmake ninja clang make python curl

```


---


## 第二部分:編譯 Llama.cpp(OpenCL 版本)


### 1. 下載 llama.cpp 原始碼

```bash

cd ~

git clone https://github.com/ggml-org/llama.cpp.git

cd llama.cpp

```


### 2. 設定 OpenCL 環境

```bash

# 測試 OpenCL 是否正常

export LD_LIBRARY_PATH=/vendor/lib64

clinfo

```


應該顯示:

```

Platform Name   : QUALCOMM Snapdragon(TM)

Device Name     : QUALCOMM Adreno(TM) 830

```


### 3. 編譯(使用 OpenCL)

```bash

cd ~/llama.cpp


cmake -B build-android \

  -DCMAKE_BUILD_TYPE=Release \

  -DGGML_OPENCL=ON \

  -DGGML_OPENCL_EMBED_KERNELS=ON \

  -DGGML_OPENCL_USE_ADRENO_KERNELS=ON \

  -DBUILD_SHARED_LIBS=ON


cmake --build build-android -j$(nproc)

```


---


## 第三部分:下載模型


### 建議模型(記憶體限制)


| 模型 | 大小 | 記憶體需求 |

|-----|------|----------|

| gemma-2-2b-it-Q4_0 | ~1.5GB | 較低,推薦 |

| Qwen3-0.8B-Q4_0 | ~500MB | 最低 |

| gemma-4-E2B-it-Q4_0 | ~1.8GB | 中等 |


### 下載模型

```bash

# 自動下載到緩存

export LD_LIBRARY_PATH=/vendor/lib64

./build-android/bin/llama-server -hf unsloth/gemma-2-2b-it-GGUF:Q4_0

```


---


## 第四部分:啟動 Llama Server


```bash

export LD_LIBRARY_PATH=/vendor/lib64


cd ~/llama.cpp


./build-android/bin/llama-server \

  -hf unsloth/gemma-2-2b-it-GGUF:Q4_0 \

  -ngl 20 \

  -c 4096 \

  --host 0.0.0.0 \

  --port 8080

```


**參數說明:**

- `-ngl 20`:使用 GPU 加速層數(Adreno 830 約 20 層)

- `-c 4096`:Context 長度

- `--host 0.0.0.0`:允許其他設備連接


---


## 第五部分:上網搜尋 + AI 對話


### 建立搜尋腳本


建立 `~/web_search_llama.py`:


```python

#!/usr/bin/env python3

"""

網頁搜尋 + llama.cpp AI 分析

"""


import sys

import requests

import openai


LLAMA_SERVER = "http://localhost:8080/v1"

MODEL = "gemma"


def web_search(query, num_results=5):

    """用 DuckDuckGo 搜尋"""

    print(f"🔍 搜尋: {query}")

    url = f"https://duckduckgo.com/html/?q={requests.utils.quote(query)}"

    headers = {"User-Agent": "Mozilla/5.0"}

    try:

        resp = requests.get(url, headers=headers, timeout=10)

        import re

        links = re.findall(r'<a class="result__a" href="([^"]+)"[^>]*>([^<]+)</a>', resp.text)

        results = []

        for href, title in links[:num_results]:

            if href.startswith('http'):

                results.append({"title": title.strip(), "url": href})

        return results if results else ["找不到結果"]

    except Exception as e:

        return [f"搜索失敗: {e}"]


def fetch_web(url):

    """抓取網頁內容"""

    try:

        response = requests.get(url, timeout=10, headers={"User-Agent": "Mozilla/5.0"})

        text = response.text

        import re

        text = re.sub(r'<[^>]+>', '', text)

        text = ' '.join(text.split())

        return text[:3000]

    except Exception as e:

        return f"錯誤: {e}"


def chat(message):

    print("\n🔍 搜尋中...")

    results = web_search(message)

    print(f"找到 {len(results)} 個結果")


    all_content = ""

    for i, r in enumerate(results[:3]):

        print(f"{i+1}. {r.get('title', r)}")

        if isinstance(r, dict) and 'url' in r:

            content = fetch_web(r['url'])

            all_content += f"\n\n--- {r.get('title')} ---\n{content}\n"


    prompt = f"根據以下搜尋結果回答:{message}\n\n{all_content}"


    try:

        client = openai.OpenAI(api_key="dummy", base_url=LLAMA_SERVER)

        response = client.chat.completions.create(

            model=MODEL,

            messages=[{"role": "user", "content": prompt}],

            temperature=0.7,

            max_tokens=500

        )

        return response.choices[0].message.content

    except Exception as e:

        return f"錯誤: {e}"


if __name__ == "__main__":

    print("🎯 AI 搜尋助手(輸入問題,或按 Ctrl+C 離開)")

    while True:

        try:

            msg = input("\n你: ").strip()

            if not msg:

                continue

            print(f"\nAI: {chat(msg)}")

        except KeyboardInterrupt:

            break

```


### 使用方式


1. 先啟動 llama-server(終端機 1):

```bash

export LD_LIBRARY_PATH=/vendor/lib64

cd ~/llama.cpp

./build-android/bin/llama-server -hf unsloth/gemma-2-2b-it-GGUF:Q4_0 -ngl 20 -c 4096 --host 0.0.0.0 --port 8080

```


2. 啟動搜尋腳本(終端機 2):

```bash

python ~/web_search_llama.py

```


3. 輸入問題,例如:

```

你: 今天天氣如何?

```


---


## 第六部分:測試結果


### OpenCL 偵測成功

```

clCreateContextFromType(NULL, CL_DEVICE_TYPE_GPU)  Success (1)

  Platform Name   : QUALCOMM Snapdragon(TM)

  Device Name     : QUALCOMM Adreno(TM) 830

```


### 執行時顯示

```

ggml_opencl: selecting device: QUALCOMM Adreno(TM) 830

ggml_opencl: using kernels optimized for Adreno (GGML_OPENCL_USE_ADRENO_KERNELS)

```


---


## 常見問題


### Q1:無法偵測 OpenCL?

```bash

# 檢查路徑

ls /vendor/lib64/libOpenCL.so


# 設定環境

export LD_LIBRARY_PATH=/vendor/lib64

```


### Q2:模型載入失敗?

- 確認使用 b5026 版本:`git checkout b5026`

- 或使用支援的模型:gemma-2-2b, Qwen3-0.8B


### Q3:記憶體不足?

- 減少 `-ngl` 數值(從 20 降到 10)

- 使用更小的模型


### Q4:gemma-4 需要 64K context?

- gemma-4-e2b 支援 6400 context

- 直接使用:`./build-android/bin/llama-server -hf unsloth/gemma-4-E2B-it-GGUF:Q4_0 -ngl 20 -c 6400`


---


## 總結


✅ 小米 15 + Adreno 830 可以運行本地 AI

✅ 使用 OpenCL 加速

✅ 可上網搜尋 + AI 分析

✅ 支援 gemma-2, gemma-4, Qwen3 等模型


需要更多模型或優化性能的可以繼續探索!


---


**更新日**:2025年

**適用**:小米 15 / Snapdragon 8 Elite / Adreno 830



cd ~/llama.cpp


export LD_LIBRARY_PATH=/vendor/lib64:$LD_LIBRARY_PATH


./build-android/bin/llama-server \

  -hf unsloth/gemma-4-E4B-it-GGUF:Q4_0 \

  -ngl 20 \

  -c 6400 \

--mlock \

  --host 0.0.0.0 \

  --port 8080



 python web_search_llama.py


沒有留言: