使用 OpenCode 与 Qwen3.8-27B 模型运行小型游戏或进行网页浏览:仅需16GB显存
摘要
本文将提供一份逐步指南,介绍如何在16GB显存的笔记本电脑上运行Qwen3.8-27B人工智能模型,涵盖exllamav3和tabbyAPI等工具的安装、配置以及性能基准测试。
过去,我使用过 llama.cpp,但听说 exl3 量化格式能提供更好的精度,因此我尝试了 exllamav3/tabbyAPI。在问了几个问题后,它就能在没有交互的情况下编写出所示的简单 HTML 游戏。以下测试在一台配备 NVIDIA RTX A5000 笔记本电脑版(16 GB)GPU 的笔记本上进行。使用 3 bpw 模型和 6 bit/5 bit KV 缓存,配合 MTP,最大上下文长度约为 110k tokens。这为代码生成提供了约 55 tokens/s 的解码速度,而对于 MTP 无帮助的内容(如复杂计算)则约为 10 tokens/s。如果不使用 MTP,则可以尝试 3.5 或 4 bpw 模型或更长的上下文长度。
**安装 tabbyAPI/exllamav3**
- 安装最新的 Nvidia 驱动程序
- 安装 Git(例如:`sudo apt install git` 或在 Windows 上使用 `winget install -e --id Git.Git`)
- 安装 uv Python 包管理器:https://docs.astral.sh/uv/getting-started/installation/(例如:`curl -LsSf https://astral.sh/uv/install.sh | sh` 或 `winget install --id=astral-sh.uv -e`)
- 在某处创建文件夹并安装 tabbyAPI:
```bash
git clone https://github.com/theroyallab/tabbyAPI
cd tabbyAPI
uv venv --python 3.13 .venv
uv pip install -e ".[cu13]"
```
- 测试 CUDA 是否工作(在 Linux 上,使用 `.venv/bin/python`):
```bash
.venv/Scripts/python -c "import torch; print(torch.__version__, torch.cuda.is_available(), torch.cuda.get_device_name(0))"
```
- 在空间足够的地方创建一个 "models" 文件夹,下载模型 turboderp/Qwen3.8-27B-exl3:
```bash
mkdir models
uvx hf download turboderp/Qwen3.8-27B-exl3 --revision SC_3.00bpw_H4 --local-dir models/qwen3.8-27b
```
- 从 froggeric/Qwen-Fixed-Chat-Templates 获取最新的 chat_template.jinja 并替换。
- 返回克隆的 tabbyAPI 文件夹,创建一个如下所示的 `config.yml` 文件(以 `config_sample.yml` 文件为示例):
```yaml
network:
disable_auth: true
model:
model_dir: e:/models # 模型文件夹的路径
model_name: qwen3.8-27b # 下载的文件夹名称
cache_mode: 6,5 # K 和 V 缓存量化,位数从 2-8
cache_size: 109824 # 必须能被 256 整除,例如使用 `.venv/Scripts/python -c 'print(110000//256*256)'` 获取下一个较小的值
max_batch_size: 1 # 仅允许 1 个并行请求以节省显存
tool_format: qwen3_coder
vision: true
draft_model: # 可以移除以节省显存
draft_mode: mtp
draft_cache_mode: Q8 # 可以是 'FP16'、'Q8'、'Q6'、'Q4'
draft_num_tokens: 5 # 通常 2-6 的值效果最佳
memory:
sysmem_recurrent_cache: 8192 # 系统内存中循环缓存的最大大小,单位 MB(默认:4096),降低以节省普通内存
sysmem_kv_cache: 8192 # 系统内存二级 K/V 缓存大小,单位 MB(默认:0),移除以节省系统内存
```
- 启动 tabbyAPI:
```bash
.venv/Scripts/python main.py
```
**测量性能**
创建 Python 脚本 `speed.py` 并用 `.venv/Scripts/python speed.py` 运行它:
```python
import json
import time
import requests
MODEL = "qwen3.8-27b"
API_URL = "http://127.0.0.1:5000"
PROMPT = """
Write a complete Python implementation of a production-quality LRU cache.
Requirements:
- Use type hints throughout.
- Include detailed docstrings.
- Support: get(key), put(key, value), remove(key), clear(), len()
- Use a doubly linked list and hash map.
- Include custom exceptions.
- Include a comprehensive unittest test suite with at least 20 test cases.
- Follow PEP8 conventions.
Return only Python code.
"""
payload = {
"model": MODEL,
"messages": [{"role": "user", "content": PROMPT}],
"max_tokens": 10000,
"stream": True,
"chat_template_kwargs": {"enable_thinking": False}
}
start_time = time.perf_counter()
first_token_time = None
stream_end_time = None
full_response_content = ""
with requests.post(API_URL + "/v1/chat/completions", json=payload, timeout=120, stream=True) as response:
response.raise_for_status()
print("Response:")
for line in response.iter_lines():
if line.startswith(b"data:"):
data = line[6:]
if data.strip() == b"[DONE]":
break
try:
chunk = json.loads(data)
if 'choices' in chunk and chunk['choices'] and (chunk['choices'][0]['delta'].get('content') or chunk['choices'][0]['delta'].get('reasoning')):
if first_token_time is None:
first_token_time = time.perf_counter()
if chunk['choices'][0]['delta'].get('content'):
token_text = chunk['choices'][0]['delta']['content']
else:
token_text = chunk['choices'][0]['delta']['reasoning']
full_response_content += token_text
print(token_text, end="", flush=True)
except json.JSONDecodeError:
pass
stream_end_time = time.perf_counter()
print("\n" + "-"*20)
ttft = first_token_time - start_time
stream_duration = stream_end_time - first_token_time
total_output_tokens = requests.post(API_URL + "/v1/token/encode", json={"add_bos_token": False, "text": full_response_content}).json()["length"]
if stream_duration > 0:
tokens_per_second = total_output_tokens / stream_duration
else:
tokens_per_second = float('inf')
print(f"Time to first token (TTFT): {ttft:.2f}s")
print(f"Completion tokens: {total_output_tokens}")
print(f"Stream duration (first to last token): {stream_duration:.2f}s")
print(f"Tokens per second (T/s): {tokens_per_second:.2f}")
```
我得到了 56.3 tokens/s。
**安装 OpenCode**
OpenCode 通常在 Linux 上运行得更好,因此在 Windows 上工作时我将其安装在 WSL 中,但它也可以直接作为 Windows 应用程序使用。对于 OpenCode,我建议先安装 Node.js(例如:`apt install npm` 或在 Windows 上使用 `winget install -e --id OpenJS.NodeJS`)。由于我们的上下文长度有限,我建议安装一个比内置的更好的压缩插件,例如 `magic-compact`。
我使用的 OpenCode 配置(`~/.config/opencode/opencode.jsonc`)如下:
```json
{
"$schema": "https://opencode.ai/config.json",
"plugin": [
"opencode-anthropic-auth@latest",
"opencode-copilot-auth@latest",
"magic-compact"
],
"share": "disabled",
"provider": {
"local": {
"npm": "@ai-sdk/openai-compatible",
"name": "local (OpenAI Compatible)",
"options": {
"baseURL": "http://127.0.0.1:5000/v1",
"apiKey": "1234"
},
"models": {
"qwen3.8-27b": {
"name": "Qwen3.8 27B",
"interleaved": {
"field": "reasoning_content"
},
"limit": {
"context": 109824,
"output": 32000
},
"temperature": true,
"reasoning": true,
"attachment": false,
"tool_call": true,
"modalities": {
"input": ["text", "image"],
"output": ["text"]
},
"cost": {
"input": 0,
"output": 0,
"cache_read": 0,
"cache_write": 0
},
"variants": {
"xhigh": {
"reasoningEffort": "xhigh"
},
"medium": {
"reasoningEffort": "medium"
},
"low": {
"reasoningEffort": "low"
}
}
}
}
}
},
"agent": {
"plan": {
"model": "local/qwen3.8-27b"
}
},
"model": "local/qwen3.8-27b",
"small_model": "local/qwen3.8-27b",
"mcp": {
"playwright": {
"type": "local",
"command": [
"npx",
"@playwright/mcp@latest",
"--caps",
"vision,pdf,devtools",
"--browser=firefox"
],
"enabled": true
}
}
}
```
我建议使用推理力度(Ctrl-t)为 "medium",因为 "xhigh" 可能会产生过多的输出 tokens。对于 Playwright,我们需要先安装一个浏览器:
```bash
npx @playwright/mcp install-browser --with-deps firefox
```
现在,以下操作应该可以工作:
```bash
opencode --prompt "Can you check for me on www.meteoschweiz.ch the weather for Zurich?"
```
要创建上面的简单 HTML 游戏,我在计划模式下(按 Tab 切换模式)输入了以下内容:
"I want to build a simple HTML game where you can drive a car with the keyboard arrow keys (similar like old versions of Mario Kart, but just one car driving without opponents is enough)."
过了一会儿,它问了我一些问题。然后,我切换到 "Build" 模式并用 "Start the implementation" 启动了它。没有任何其他交互,它就完成了这个小游戏。
相似文章
在搭载RTX 4060(8GB)的笔记本电脑上运行Qwen3.6-35B-A3B——哪些有效、哪些无效以及一个令人意外的推测解码结果
详细记录了在8GB笔记本GPU上运行Qwen3.6-35B-A3B MoE模型的经历,涵盖有效优化(如--no-mmap和VRAM余量)、意料之外的发现(推测解码相比基准测试提升26%的速度)以及Windows和CPU瓶颈的陷阱。
在16GB显存+32GB内存下运行Qwen 3.8 - 写给贫民窟GPU玩家的实用/趣味指南
一位Reddit用户分享了如何在拥有16GB显存和32GB内存的系统上,通过激进量化及特定llama.cpp设置成功运行Qwen 3.8 Next MoE模型,实现了在有限硬件上高效运行大模型的效果。
@UnslothAI:Qwen3.8-27B 即将发布!可在 17GB RAM/VRAM 配置上本地运行。
阿里巴巴宣布 Qwen3.8-27B 开源权重版本发布,可在 17GB RAM/VRAM 上本地运行,同时还有更大的 Qwen3.8-Max。
我在有限显存(16-20GB)上对 Qwen 3.8 27B 的测试
本文测试了在有限显存环境下各种量化版本的 Qwen 3.8 27B AI 模型,比较了它们在动画生成、应用开发和单词生成等任务上的表现。
在单卡5090上本地运行Qwen 3.8 27B的测试
本文展示了在单卡5090 GPU上本地运行Qwen 3.8 27B AI模型的能力,使用Row-Bot生成丰富的动画,展示从语言合成到物理模拟的任务。