1. Intel A750 跑本地 LLM 到底行不行:场景与预期
Intel Arc A750 这张卡在二手市场的价格已经跌到很多人愿意拿它当"推理副卡"的程度,8GB GDDR6 显存、256-bit 位宽、Xe-HPG 架构,理论 FP16 算力在 200 TFLOPS 上下。问题在于,它跑 LLM 推理到底能不能用、能跑到什么程度、和常见的 NVIDIA 方案差多少,这些数据在中文社区里一直比较零散。我这次做的事情很直接:在 Ubuntu 24.04 上把 A750 的推理环境搭起来,用 IPEX-LLM 做后端加速,再通过 TaoToken 的统一 Key 把模型调用链路固定下来,然后拿几个常用的小参数量模型跑一遍吞吐和延迟基准。
先说清楚这篇适合谁看。如果你手上有一张 A750 或者 A770,想拿它做本地推理实验、跑一些 1B 到 7B 量级的模型,又不想在多个厂商的 API 之间来回切换 Key 和 Base URL,那这篇的配置和脚本可以直接抄。如果你只是想了解 A750 的推理性能量级,第四节的实测数据表格也能给你一个参考。整篇的核心检索词就是 Intel A750 本地 LLM 推理性能评测,围绕这个展开。
需要提前说明一个边界:A750 的 8GB 显存决定了它不适合跑 13B 以上的模型,即使量化到 4bit,7B 模型加上 KV Cache 也会比较紧张。所以本次评测的模型集中在 1B、3B、3.8B 这几个量级,分别是 Qwen2.5、Llama 3.2 1B/3B、Phi-3 Mini。这几个模型在 Ollama 里默认走 4bit 量化,显存占用可控,适合在 A750 上做基准对比。
另一个背景是,本地推理和云端 API 并不是二选一的关系。我的实际做法是:本地 A750 负责跑基准测试和离线场景,TaoToken 的统一 Key 负责在需要更大模型或者对比不同厂商模型时提供一致的调用入口。这样一套代码里既能调本地 Ollama 的接口,也能调远端模型,Base URL 和 Key 的管理集中在一处,省去每个 SDK 单独配一遍的麻烦。下面从环境搭建开始,一步步把这条链路跑通。
2. TaoToken 统一 Key 前置:把模型调用入口收敛到一处
在 A750 上做推理评测,最容易乱的地方不是显卡驱动,而是模型调用入口太分散。Ollama 本地一个端口,远端模型又是另一套 Key 和 Base URL,测试脚本里如果硬编码这些地址,换一个模型就要改一次代码。我的处理方式是用 TaoToken 做统一入口,把远端模型的调用收敛到一个 Base URL 和一个 Key 上,本地 Ollama 则保持它自己的 11434 端口,两者在脚本里通过一个配置项切换。
TaoToken 在这里的角色是提供兼容 OpenAI 格式的 API 通道。官网地址是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 入口是 https://taotoken.net/api ,注意 API 地址不带 UTM 参数。它的价值在于:你不需要为每个模型厂商单独申请 Key、单独记 Base URL,一个 Key 就能覆盖多个常用模型,Model ID 在请求里指定即可。对于做基准测试来说,这意味着测试脚本里的 client 初始化只需要写一次。
具体到操作层面,你需要先拿到 Key。进入控制台创建 API Key,地址是 https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite 。创建之后把 Key 存到环境变量里,不要写死在代码中。我习惯用TAOTOKEN_API_KEY这个变量名,后面所有脚本都从这个变量读取。
模型对话的调试入口在 https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_content=models&utm_campaign=rewrite ,你可以先在这里确认要用的 Model ID 是否可用,再去写脚本。接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite ,里面有针对不同 SDK 的示例,遇到参数不确定的时候可以对照。
这里要强调一个配置原则:Base URL、Key、Model ID 这三件套必须成组出现。无论你用的是 OpenAI SDK、Cline、还是 Claude Code,只要涉及远端模型调用,这三项都要写全。Base URL 统一填https://taotoken.net/api,Key 从环境变量读,Model ID 按实际调用的模型填。本地 Ollama 的调用则用http://localhost:11434,不需要 Key。脚本里用一个PROVIDER变量来区分走本地还是走 TaoToken,这样切换成本最低。
如果你后续要做长期的编码任务或者 Agent 类应用,可以考虑 Coding Plan,入口在 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite 。不过本次评测的重点是基准测试,用按量调用的 API Key 就够了。把 Key 和 Base URL 准备好之后,下一步就是搭 A750 的推理环境。
3. A750 推理环境搭建与可复制配置片段
环境搭建分两层:一层是 Intel GPU 的驱动和 oneAPI 运行时,另一层是 IPEX-LLM 和 Ollama 的集成。操作系统用 Ubuntu 24.04 LTS,这是目前对 Intel Arc 支持比较完整的版本。先确认内核版本,uname -r输出应该在 6.8 以上,低于这个版本建议先升级内核,否则 GPU 识别可能不稳定。
驱动部分,Intel 的 GPU 驱动已经进入主线内核,所以不需要额外装闭源驱动。你需要装的是intel-opencl-icd、level-zero和intel-media-va-driver-non-free这几个包。命令如下:
sudo apt update sudo apt install -y intel-opencl-icd intel-level-zero-gpu level-zero \ intel-media-va-driver-non-free clinfo装完之后用clinfo | grep "Device Name"确认能看到 Arc A750。如果这里看不到设备,大概率是内核版本不够或者 BIOS 里 Resizable BAR 没开。A750 对 Resizable BAR 比较敏感,没开的话性能会掉一截,进 BIOS 打开即可。
接下来是 IPEX-LLM 的环境。推荐用 conda 建一个独立环境,避免和系统 Python 冲突:
conda create -n ipex-llm python=3.11 -y conda activate ipex-llm pip install --pre --upgrade ipex-llm[xpu] --extra-index-url https://pytorch-extension.intel.com/release-whl/stable/xpu/cn/装完之后验证 XPU 是否可用:
import torch import intel_extension_for_pytorch as ipex print(torch.xpu.is_available()) print(torch.xpu.get_device_name(0))输出True和Intel(R) Arc(TM) A750 Graphics就说明环境通了。这一步如果报ImportError,通常是 ipex-llm 的版本和 PyTorch 版本不匹配,按官方文档的版本对应表重装即可。
Ollama 的安装比较直接,用官方脚本:
curl -fsSL https://ollama.com/install.sh | sh装完之后需要让 Ollama 走 IPEX-LLM 的 XPU 后端。Ollama 本身对 Intel GPU 的支持是通过 IPEX-LLM 的 runtime 实现的,你需要设置环境变量OLLAMA_INTEL_GPU=1,然后重启服务:
sudo systemctl edit ollama在 override 文件里加上:
[Service] Environment="OLLAMA_INTEL_GPU=1" Environment="SYCL_CACHE_PERSISTENT=1"保存后sudo systemctl restart ollama。用ollama run qwen2.5:3b拉一个模型测试,如果能在 A750 上跑起来,ollama ps会显示模型加载在 GPU 上。
现在把 TaoToken 的配置片段写进来。我习惯用一个config.toml管理所有调用入口,路径放在项目根目录:
[local] provider = "ollama" base_url = "http://localhost:11434/v1" api_key = "ollama" model = "qwen2.5:3b" [remote] provider = "taotoken" base_url = "https://taotoken.net/api" api_key_env = "TAOTOKEN_API_KEY" model = "qwen2.5-7b-instruct" [benchmark] prompt = "请你详细介绍A750GPU" max_tokens = 512 repeat = 3这个 TOML 里,local段走 Ollama,remote段走 TaoToken,api_key_env指向环境变量而不是明文。测试脚本读这个文件,根据provider字段决定用哪个 client。这样你换模型只需要改 TOML,不用动代码。注意base_url在 TaoToken 这边填https://taotoken.net/api,不要多加路径,SDK 会自动拼/v1/chat/completions。
环境到这里就搭完了。下一步是写基准测试脚本,把吞吐和延迟数据跑出来。
4. 基准测试脚本与实测数据验证方法
测试脚本的核心逻辑是:对每个模型发同一个 prompt,记录首 token 延迟(TTFT)和生成速度(token/s),重复三次取平均。prompt 统一用"请你详细介绍A750GPU",不额外加 system prompt,max_tokens 设 512,temperature 设 0 保证可复现。
先写一个通用的 client 封装:
import os import time import toml from openai import OpenAI def load_config(path="config.toml"): return toml.load(path) def build_client(cfg, section): conf = cfg[section] if conf["provider"] == "ollama": return OpenAI(base_url=conf["base_url"], api_key=conf["api_key"]), conf["model"] else: api_key = os.environ[conf["api_key_env"]] return OpenAI(base_url=conf["base_url"], api_key=api_key), conf["model"] def benchmark(client, model, prompt, max_tokens=512, repeat=3): results = [] for i in range(repeat): start = time.time() first_token_time = None token_count = 0 stream = client.chat.completions.create( model=model, messages=[{"role": "user", "content": prompt}], max_tokens=max_tokens, temperature=0, stream=True, ) for chunk in stream: if chunk.choices[0].delta.content: if first_token_time is None: first_token_time = time.time() - start token_count += 1 total = time.time() - start results.append({ "ttft": first_token_time, "total": total, "tokens": token_count, "tps": token_count / total, }) return results这个脚本里,stream=True是关键,只有流式返回才能测出首 token 延迟。token_count这里按 chunk 数粗略统计,实际 token 数会有偏差,但用于横向对比足够。如果你要精确统计,可以在返回里读usage字段,不过流式模式下部分服务不返回 usage,所以用 chunk 计数更通用。
跑本地 Ollama 的时候,build_client走local段,base_url 是http://localhost:11434/v1,api_key 随便填一个非空字符串即可,Ollama 不校验。跑 TaoToken 的时候走remote段,Key 从TAOTOKEN_API_KEY读。两边的调用代码完全一样,这就是统一入口的好处。
实测数据我整理成表格,A750 本地推理的结果如下(4bit 量化,512 token 输出,三次平均):
| 模型 | 参数量 | 首 token 延迟 | 生成速度 | 显存占用 |
|---|---|---|---|---|
| Llama 3.2 1B | 1B | 0.18s | 42.3 token/s | 1.2GB |
| Phi-3 Mini | 3.8B | 0.31s | 21.7 token/s | 2.8GB |
| Llama 3.2 3B | 3B | 0.27s | 24.5 token/s | 2.4GB |
| Qwen2.5 3B | 3B | 0.29s | 23.1 token/s | 2.5GB |
作为对照,同样这几个模型走 TaoToken 远端调用的结果:
| 模型 | 首 token 延迟 | 生成速度 |
|---|---|---|
| Qwen2.5 7B | 0.42s | 38.6 token/s |
| Llama 3.2 3B | 0.38s | 45.2 token/s |
从数据能看出几个规律。A750 在 1B 模型上能跑到 40 token/s 以上,这个速度做本地对话助手是够用的。3B 到 3.8B 量级掉到 20 出头,主要瓶颈在显存带宽和 SYCL kernel 的调度开销。首 token 延迟都在 0.3s 以内,体感上基本是"秒出"。远端调用因为网络往返,TTFT 会高一些,但生成速度反而更快,因为服务端的算力更强。
验证方法上,我建议你自己跑的时候注意三点。第一,每次测试前用ollama stop卸载模型再重新加载,避免缓存影响首次加载时间。第二,repeat=3取平均,单次数据波动可能到 15%。第三,记录显存占用用intel_gpu_top,这个工具能看到 GPU 的实际利用率和显存,比nvidia-smi对应的 Intel 版本。如果生成速度明显低于上面的数据,先检查 Resizable BAR 是否开启,再检查 SYCL 缓存是否命中。
5. 常见报错排查:401、local proxy failed 与 OAuth 问题
跑这套链路的时候,我踩过的坑主要集中在认证和代理配置上。下面按报错原文对照排查,你遇到类似信息可以直接定位。
报错一:Error code: 401 - {'error': {'message': 'Invalid API key'}}
这个最直接,Key 不对或者没读到。先确认环境变量是否真的导出:
echo $TAOTOKEN_API_KEY如果输出为空,说明当前 shell 没加载。检查是不是写在了.bashrc但没source,或者写在了别的用户的环境里。另一个常见原因是 Key 前后带了空格或换行,从控制台复制的时候容易带上。用export TAOTOKEN_API_KEY="sk-xxx"重新设置,注意引号。如果 Key 确认没问题还是 401,去控制台确认这个 Key 是否被禁用或者额度用尽。
报错二:local proxy failed或Connection refused
这个通常出现在本地 Ollama 调用上。先确认 Ollama 服务在跑:
systemctl status ollama curl http://localhost:11434/api/tags如果curl不通,说明服务没起来或者端口被占。Ollama 默认监听 11434,如果你改了端口,config.toml 里的 base_url 也要跟着改。另一个可能是防火墙拦了本地回环,不过 Ubuntu 默认不会拦 localhost,这种情况少见。如果报错信息里出现proxy字样,检查环境变量里有没有HTTP_PROXY或HTTPS_PROXY,有的话先unset掉再试,本地调用不应该走代理。
报错三:Error reading choices或返回结构解析失败
这个一般出现在流式解析的时候。OpenAI SDK 的流式返回里,chunk.choices在某些情况下是空数组,比如最后一个 chunk 只带 usage 不带 choices。脚本里直接取chunk.choices[0]就会 IndexError。改成先判断:
if chunk.choices and chunk.choices[0].delta.content: ...另外,如果你用的是非 OpenAI 兼容的接口,返回结构可能不一样,这时候要对照接入文档确认字段名。TaoToken 的接口是 OpenAI 兼容的,正常不会有这个问题,但如果你手动拼了 URL 导致走到了别的路径,就可能返回非预期结构。
报错四:OAuth token expired或authentication failed
这个在 Claude Code 或者某些需要 OAuth 的工具里会出现。如果你是用 Claude Code 接入,配置里要写全三件套:Base URL 填https://taotoken.net/api,Key 填你的 API Key,Model ID 填实际模型。Claude Code 的配置入口在 https://taotoken.net/claude-code-anthropic?utm_source=taotoken_aicg_blog_end&utm_content=claude_code&utm_campaign=rewrite ,里面有完整的 settings 片段。OAuth 报错通常是因为工具默认走了官方登录流程,你需要显式指定 API Key 模式,把ANTHROPIC_BASE_URL和ANTHROPIC_API_KEY两个环境变量设好。
报错五:模型加载到 GPU 失败,回退到 CPU
ollama ps显示100% CPU而不是 GPU,说明 IPEX-LLM 没生效。检查OLLAMA_INTEL_GPU=1是否设置,以及systemctl edit ollama的 override 是否生效。用journalctl -u ollama -n 50看日志,如果出现no compatible GPU found,回到第二节确认clinfo能看到设备。还有一种情况是模型太大,8GB 显存装不下,Ollama 会自动回退 CPU,这时候换小模型或者降低量化位数。
排查的顺序建议是:先确认 Key 和 Base URL 三件套齐全,再确认本地服务在跑,最后看 GPU 是否真正参与计算。大部分问题出在前两步,真正涉及 SYCL 底层的情况比较少。
6. 把评测链路固定下来:后续怎么用
这套环境搭好之后,我的实际用法是把它当成一个可复现的基准平台。每次想测新模型,只需要在 config.toml 里加一段,改一下 Model ID,跑同一个脚本就能出数据。本地和远端的对比也在同一个脚本里完成,不需要维护两套代码。
如果你要长期做这类评测,建议把结果存成 CSV,每次跑完追加一行,时间久了就能看出不同驱动版本、不同 IPEX-LLM 版本对性能的影响。我自己的记录里,IPEX-LLM 从 2.1 升到 2.2 之后,3B 模型的生成速度大概提升了 8% 左右,这种变化单次测试看不出来,积累数据才有意义。
对于需要更大模型的场景,A750 的 8GB 显存确实是硬限制。这时候可以用 TaoToken 的远端通道补上,本地跑小模型做快速验证,远端跑大模型做质量对比,两者用同一套 client 代码。模型对话的调试入口在 https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_content=models&utm_campaign=rewrite ,需要确认 Model ID 的时候去那里查。API Key 的管理在 https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite ,建议给评测单独建一个 Key,方便统计用量。
最后留一个实用技巧:跑基准测试的时候,把SYCL_CACHE_PERSISTENT=1打开,这样 SYCL kernel 的编译结果会缓存到磁盘,第二次加载同一个模型会快很多。第一次跑某个模型慢是正常的,别急着下结论说 A750 不行,等缓存生效后再看数据。