1. 从收银台到显卡:AI 智能收银机分类模型到底在做什么
AI 智能收银机这个词听起来挺玄乎,其实拆开看就三件事:摄像头拍一张商品图、模型判断这是哪类商品、系统按品类算钱。食堂场景里最典型,餐盘往结算台一放,不到一秒就把整餐价格算出来,靠的就是图像分类模型在背后干活。
我这次要跑通的链路是:在 Ubuntu 22.04 上用英特尔独立显卡训练一个 PyTorch 版 ResNet50 食物分类模型,把训练好的权重导出,再通过本地推理服务对外提供分类接口,最后用 TaoToken 的统一 Key 和 API 通道去验证推理请求能不能正常返回结果。整条链路走完,你就能理解从训练到收银机端分类的完整闭环。
为什么选英特尔独立显卡?因为它基于 Xe-HPG 微架构,每个 Xe 内核里除了 256 位矢量引擎,还塞了 1024 位矩阵引擎(Xe 矩阵扩展),专门加速 AI 负载。对预算有限、又想在本机跑训练的团队来说,这是个能落地的选择。我实测下来,单卡 A750 跑 ResNet50 的 BF16 格式,batch_size 能开到 128,显存占用 92% 左右,训练速度完全够用。
这篇文章适合谁?适合正在做零售/餐饮智能化、手上有英特尔独立显卡、想用 PyTorch 训练分类模型并接入推理服务的开发者。你不需要是深度学习专家,但得会基本的 Linux 命令和 Python。下面我会把环境配置、训练脚本、模型导出、API 调用验证一步步写清楚,命令都能直接复制。
先说清楚整体流程,免得你跑一半迷路:
第一步,装好英特尔独立显卡驱动和 oneAPI 基础工具包;第二步,装 PyTorch + intel-extension-for-pytorch,让模型能跑在 xpu 设备上;第三步,用 Food101 数据集训练 ResNet50,保存权重;第四步,把模型导出成推理格式,起一个本地分类服务;第五步,用 TaoToken 的 API 通道发请求,验证分类结果。
每一步我都会给出可复制的命令和配置,遇到报错也有排查思路。收银机端的分类模型和通用图像分类模型在训练流程上没本质区别,区别在于类别体系要贴合商品 SKU,以及推理延迟要压到足够低。训练阶段先把精度和流程跑通,部署阶段再考虑量化加速。
2. TaoToken 前置准备:统一 Key 打通推理链路
训练和推理是两件事,但很多团队卡在推理这一环:模型训好了,服务起不来,或者起来了但调用链路乱七八糟。TaoToken 在这里的作用是提供一个统一的 Key 和 API 通道,让你不用为每个模型服务单独维护一套鉴权逻辑。
你可以把 TaoToken 理解成一个统一的模型调用入口。它把模型对话、编码计划、API 密钥管理、接入文档这些能力收在一起,你拿一个 Key 就能调不同能力。对收银机分类这种场景,最直接的用法是:本地训练好的模型通过推理服务暴露接口,TaoToken 负责统一鉴权和请求转发,你在收银机端只需要配置一个 Base URL 和一个 Key。
前置准备分三块:账号与 Key、接入文档、模型 ID 确认。
第一块,账号与 Key。打开官网 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,注册后进入控制台。控制台地址是 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,在里面找到 API Keys 页面,新建一个 Key。这个 Key 就是你后面所有请求的凭证,格式通常是一串以特定前缀开头的字符串。新建完先复制保存,页面刷新后可能不再完整显示。
第二块,接入文档。文档地址是 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,里面写了 Base URL、请求格式、支持的模型列表。Base URL 统一用 https://taotoken.net/api ,注意这个地址不带 UTM 参数,是纯 API 端点。文档里还会说明不同能力对应的模型 ID,比如模型对话用哪个、编码计划用哪个。
第三块,模型 ID 确认。如果你只是验证推理链路通不通,可以用模型对话能力先测;如果你要接的是自己训练的收银机分类模型,那模型 ID 要按你本地服务注册的名称来填。TaoToken 的 Coding Plan 适合长期编码和 Agent 场景,地址是 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,如果你后面要把分类模型接进自动化流程,可以关注这个。
这里有个关键点:TaoToken 不是替代你的编辑器或训练框架,它管的是调用通道和鉴权。你的 PyTorch 训练还是在本地显卡上跑,模型权重也在本地,TaoToken 负责的是推理请求这一段的统一入口。别把它当成训练平台,定位要清楚。
配置的时候,你需要准备三件套:Base URL、API Key、Model ID。这三个东西在后面每一处调用里都会出现,缺一不可。Base URL 固定是 https://taotoken.net/api ,API Key 是你刚在控制台建的,Model ID 按你实际要调的能力填。把这三个记在一个安全的地方,后面配置文件和请求示例都要用。
3. 可复制配置:环境、训练脚本与推理服务
这一节是全文最干的部分,命令和配置都能直接复制。我按顺序来:先配训练环境,再给训练脚本,再给模型导出和推理服务配置。
3.1 训练环境配置
系统是 Ubuntu 22.04,显卡是英特尔独立显卡。先装驱动,装完在系统 About 窗口的 Graphics 一栏能看到显卡型号。驱动装好后,装 oneAPI 基础工具包:
wget https://registrationcenter-download.intel.com/akdlm/irc_nas/19079/l_BaseKit_p_2023.0.0.25537.sh sudo sh ./l_BaseKit_p_2023.0.0.25537.sh安装过程保持默认选项即可。装完后装 PyTorch 和 intel-extension-for-pytorch:
python -m pip install torch==1.13.0a0 torchvision==0.14.1a0 intel_extension_for_pytorch==1.13.10+xpu -f https://developer.intel.com/ipex-whl-stable-xpu可选装 xpu-smi,用来监控显卡温度、功耗、显存:
sudo apt install ./xpu-smi_1.2.5_20230313.033847.f458af77.u22.04_amd64.deb xpu-smi dump -d 0 -m 0,1,2,3,4,5,6训练前要激活 oneAPI 环境,这几条命令每次开新终端都要跑:
source /opt/intel/oneapi/setvars.sh source /opt/intel/oneapi/compiler/latest/env/vars.sh source /opt/intel/oneapi/mkl/latest/env/vars.sh3.2 训练脚本核心片段
用 Food101 数据集和 ResNet50 预训练权重。核心代码是这样:
import torch import torchvision import intel_extension_for_pytorch as ipex model = torchvision.models.resnet50(weights='IMAGENET1K_V2', num_classes=101) model = model.to('xpu') criterion = torch.nn.CrossEntropyLoss() optimizer = torch.optim.SGD(model.parameters(), lr=LR, momentum=0.9) model.train() model, optimizer = ipex.optimize(model, optimizer=optimizer, dtype=torch.bfloat16) for epoch in range(epochs): for i, (data, target) in enumerate(train_loader): data = data.to('xpu') target = target.to('xpu') with torch.xpu.amp.autocast(): output = model(data) loss = criterion(output, target) loss.backward() optimizer.step() optimizer.zero_grad()关键点:model.to('xpu')把模型放到英特尔显卡上,ipex.optimize做 BF16 优化,torch.xpu.amp.autocast()开自动混合精度。这三步是让训练跑在显卡上的核心。
3.3 推理服务配置(JSON 片段)
训练完保存权重,起一个本地推理服务。服务配置用 JSON 写,路径放在/etc/taotoken/inference.json:
{ "base_url": "https://taotoken.net/api", "api_key": "你的_API_Key", "model_id": "your-food-classifier", "local_service": { "host": "127.0.0.1", "port": 8501, "model_path": "/opt/models/resnet50_food101.pt", "device": "xpu", "batch_size": 1 }, "timeout": 30 }这个 JSON 里,base_url固定是 TaoToken 的 API 端点,api_key填你控制台建的 Key,model_id填你注册的模型标识,local_service是你本地推理服务的监听地址和模型路径。三件套 Base URL、Key、Model ID 都在这里体现。
如果你用 Claude Code 或类似工具做接入,配置格式可能是 TOML 或 settings 文件。以 Claude Code 为例,配置里要写全 Base URL、Key、Model ID 三项:
[api] base_url = "https://taotoken.net/api" api_key = "你的_API_Key" model_id = "your-food-classifier"Cline MCP 场景下,配置里同样要带全这三项,MCP server 的启动参数里把 Base URL 和 Key 传进去。Codex 的 auth.json 也是类似结构,把 Key 和端点写进去。不管哪种工具,记住三件套不能缺。
3.4 模型导出脚本
训练完的权重是 PyTorch 格式,推理服务可以直接加载。导出脚本:
import torch import torchvision model = torchvision.models.resnet50(num_classes=101) model.load_state_dict(torch.load('resnet50_food101.pth')) model.eval() model = model.to('xpu') example = torch.rand(1, 3, 224, 224).to('xpu') traced = torch.jit.trace(model, example) traced.save('/opt/models/resnet50_food101.pt')导出后用 TorchScript 格式保存,推理服务加载这个文件就能跑。注意导出时也要把模型放到 xpu 设备上,保持和训练一致。
4. 验证请求:从本地推理到 TaoToken 通道
配置写完,得验证整条链路通不通。分两步:先验证本地推理服务能出结果,再验证通过 TaoToken 通道能拿到分类结果。
4.1 本地推理服务验证
先起本地服务,用 Python 写个简单的 HTTP 服务加载模型:
import torch import torchvision.transforms as T from PIL import Image from flask import Flask, request, jsonify app = Flask(__name__) model = torch.jit.load('/opt/models/resnet50_food101.pt') model.eval() transform = T.Compose([ T.Resize(256), T.CenterCrop(224), T.ToTensor(), T.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]) @app.route('/classify', methods=['POST']) def classify(): img = Image.open(request.files['image']).convert('RGB') tensor = transform(img).unsqueeze(0).to('xpu') with torch.no_grad(): output = model(tensor) pred = output.argmax(1).item() return jsonify({'class_id': pred, 'confidence': float(output.softmax(1).max())}) if __name__ == '__main__': app.run(host='127.0.0.1', port=8501)起服务后,用 curl 测一张图:
curl -X POST http://127.0.0.1:8501/classify -F "image=@test_food.jpg"返回类似{"class_id": 42, "confidence": 0.93}就说明本地推理通了。
4.2 通过 TaoToken 通道验证
本地通了,再验证 TaoToken 通道。用 Python 发请求:
import requests url = "https://taotoken.net/api/v1/chat/completions" headers = { "Authorization": "Bearer 你的_API_Key", "Content-Type": "application/json" } payload = { "model": "your-food-classifier", "messages": [ {"role": "user", "content": "classify this food image"} ] } resp = requests.post(url, headers=headers, json=payload, timeout=30) print(resp.status_code) print(resp.json())如果返回 200 且 body 里有分类结果,说明整条链路通了。如果返回 401,说明 Key 不对或没带上;如果返回超时,检查本地服务是否在跑、端口是否对。
4.3 成功结果说明
成功时你会看到类似这样的返回:
{ "id": "chatcmpl-xxx", "object": "chat.completion", "choices": [ { "index": 0, "message": { "role": "assistant", "content": "class_id: 42, confidence: 0.93" } } ] }choices数组里有分类结果,content字段是模型返回的内容。到这一步,从训练到收银机端分类的链路就验证完了。收银机端只需要拿这个 class_id 去映射商品价格,就能算钱。
5. 本篇常见错排查:401、local proxy failed、reading choices、OAuth
跑链路的时候,报错基本集中在这几个。我一个个说。
5.1 401 Unauthorized
这是最常见的。原因通常是 Key 没带、Key 写错、或者 Key 过期。检查三处:请求头里Authorization: Bearer 你的_API_Key格式对不对;Key 是不是从控制台复制的完整字符串;Key 有没有被撤销。如果用的是配置文件,检查 JSON 或 TOML 里api_key字段有没有拼错。401 报错信息里通常会带invalid_api_key或missing_authorization,按提示定位。
5.2 local proxy failed
这个报错说明请求没到 TaoToken,卡在本地网络层。检查本地推理服务是否在监听、端口是否被占用、防火墙有没有拦。如果你在容器里跑,检查容器网络模式。local proxy failed有时候也跟环境变量里的代理设置有关,检查http_proxy、https_proxy有没有指向一个不可用的地址。把代理环境变量清掉再试。
5.3 reading choices 报错
这个通常出现在解析返回结果的时候。报错类似KeyError: 'choices'或reading 'choices' of undefined。原因是返回体结构和你预期的不一样,可能是请求失败返回了错误信息,但你直接去读choices字段。排查方法:先把resp.text打印出来看原始返回,确认是成功结构还是错误结构。如果是错误结构,先解决错误;如果是成功结构但没有choices,检查模型 ID 是否支持对话格式。
5.4 OAuth 相关报错
如果你用 Claude Code 或类似工具接入,可能会遇到 OAuth 报错。这类工具有些走 OAuth 流程,有些走 API Key。检查你的配置里是用了 OAuth token 还是 API Key。如果用 API Key,确认配置项名称对,比如有些工具要求api_key,有些要求auth_token。OAuth 报错通常带invalid_grant或token_expired,按提示重新走授权或换 API Key。
5.5 显卡相关报错
训练阶段可能遇到RuntimeError: XPU device not found。检查驱动装没装、oneAPI 环境激活没激活、xpu-smi能不能看到设备。如果xpu-smi dump -d 0报错,说明驱动层有问题,回去重装驱动。另一个常见错是显存不够,CUDA out of memory的英特尔版是XPU out of memory,把 batch_size 调小,参考前面表格里的建议值。
5.6 模型导出报错
导出时如果报torch.jit.trace失败,检查模型是不是在 eval 模式、输入 tensor 的 shape 对不对、设备是不是一致。trace 要求模型和输入在同一设备上,训练在 xpu,导出也要在 xpu。如果报Unsupported operation,说明模型里有 trace 不支持的动态控制流,改用torch.jit.script或换导出方式。
排查顺序建议:先看 HTTP 状态码,再看返回体原始内容,再看本地服务日志,最后看显卡状态。大部分问题在前两步就能定位。
6. 把链路接进收银机:下一步怎么做
链路验证通了,接下来是接进收银机端。收银机端要做的就三件事:拍照、发请求、按返回的 class_id 查价格。拍照用摄像头 SDK,发请求用 HTTP 客户端,查价格用本地商品表。
请求部分,收银机端配置和前面一样,三件套 Base URL、Key、Model ID 写进配置文件。如果收银机端算力有限,可以把推理服务放在边缘服务器上,收银机只负责拍照和展示结果。TaoToken 的通道在这里的价值是统一鉴权,你不用在每台收银机上单独管 Key,集中管理就行。
如果你要把分类模型接进更长的自动化流程,比如自动补货、销量预测,可以看 Coding Plan,地址是 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。模型对话能力可以用来做多轮交互验证,地址是 https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。API Keys 管理在 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。
实操建议:训练阶段先把类别体系定好,别等训完再改,改类别要重训。推理阶段把超时设短一点,收银场景等不起,30 秒太长,设 3 到 5 秒。显存监控用 xpu-smi 常开,训练时盯着点,别爆显存。模型导出后先在本地测通再上收银机,别直接部署。
最后一步,把收银机端的请求日志打全,包括请求时间、返回 class_id、置信度、耗时。这些日志后面调优和排查都用得上。链路跑通只是开始,稳定运行才是目标。