
1. Gemma 本地评测与微调落地从推理基线到统一 API 调用Gemma 是 Google 基于 Gemini 同源技术推出的一系列轻量级开源大模型采用 decoder-only 架构权重完全开放同时提供预训练版本base和指令微调版本chat。目前主流规模是 2B 和 7B 两档官方除了 PyTorch 权重还提供 GGUF 版本能在消费级硬件上直接跑上下文窗口支持到 8K tokens。7B 版本的预训练数据量达到 6 万亿 token在公开榜单上超过了同尺寸的 Mistral-7B。这套东西适合谁如果你手上有单张 12GB 到 24GB 显存的卡想先跑通一个开源模型的推理基线再用 LoRA 做一次小规模微调最后把本地推理 endpoint 换成统一 API 通道来对比效果那这篇就是按这个顺序写的。我会先给环境配置和推理脚本再给 SWIFT 微调的完整参数最后演示怎么把请求切到 TaoToken 的统一 Key/API 通道完成调用验证和微调前后结果对比。整个过程不需要多卡单卡就能跟下来。2. TaoToken 前置准备统一 API 通道与 Key 获取在开始之前先把本地推理和统一 API 调用这两条路分开理解。本地推理是你自己加载权重、自己占显存统一 API 通道是把请求发到一个兼容 OpenAI 协议的服务端由服务端调度模型。TaoToken 提供的就是后者它的 API 地址是https://taotoken.net/api兼容 OpenAI 的/v1/chat/completions格式所以你原来写好的 OpenAI SDK 代码基本只需要改base_url和api_key。为什么要在 Gemma 评测里引入这一步因为本地跑 7B 模型对显存有硬要求而微调后的效果对比如果只靠本地单卡切换模型、切换 checkpoint 都要重新加载权重很费时间。把一部分验证请求走统一 API 通道可以快速拿到另一个模型或另一个版本的输出做对照省去反复加载的等待。获取 Key 的路径很直接打开https://taotoken.net/api-keys登录后在控制台创建 API Key复制出来保存好。这个 Key 就是后面所有请求里api_key字段的值。注意不要把它硬编码进提交到 Git 的脚本里建议用环境变量。模型 ID 方面TaoToken 的模型列表可以在https://taotoken.net/doc里查到调用时model字段填对应的模型标识即可。如果你后面要做长期编码或 Agent 类任务可以了解下 Coding Planhttps://taotoken.net/coding-plan它更适合持续性的调用场景单纯做模型对话验证的话用模型对话入口https://taotoken.net/models就够了。这里要强调一点TaoToken 是合规的 API 聚合通道不是任何形式的非法中转所有调用都走标准 HTTPS 和 Bearer Token 鉴权。你只需要把它当成一个兼容 OpenAI 协议的服务端来用。3. 可复制配置环境、推理脚本与微调参数先把本地环境搭起来。Python 要求 3.10 及以上PyTorch 推荐 2.0 及以上CUDA 建议 11.4 以上transformers 需要 4.38.0。装依赖pip install transformers4.38.0 torch accelerate modelscope下载 Gemma 权重用 modelscope 的 snapshot_download 最省事from modelscope import snapshot_download model_dir snapshot_download(AI-ModelScope/gemma-7b-it) print(model_dir)推理基线脚本关键是apply_chat_template拿指令微调模型的 prompt 模板from modelscope import AutoTokenizer, AutoModelForCausalLM import torch tokenizer AutoTokenizer.from_pretrained(AI-ModelScope/gemma-7b-it) model AutoModelForCausalLM.from_pretrained( AI-ModelScope/gemma-7b-it, torch_dtypetorch.bfloat16, device_mapauto ) input_text hello. messages [{role: user, content: input_text}] text tokenizer.apply_chat_template( messages, tokenizeFalse, add_generation_promptTrue ) input_ids tokenizer([text], return_tensorspt).to(cuda) outputs model.generate(**input_ids, max_new_tokens256) print(tokenizer.decode(outputs[0]))微调用 SWIFT先克隆安装git clone https://github.com/modelscope/swift.git cd swift pip install .[llm]LoRA 微调脚本用 hc3-zh 分类数据集任务是判断回答来自 human 还是 chatgptCUDA_VISIBLE_DEVICES0 \ swift sft \ --model_id_or_path AI-ModelScope/gemma-2b-it \ --sft_type lora \ --tuner_backend swift \ --template_type AUTO \ --dtype AUTO \ --output_dir output \ --dataset hc3-zh \ --train_dataset_sample 5000 \ --num_train_epochs 1 \ --max_length 2048 \ --check_dataset_strategy warning \ --lora_rank 8 \ --lora_alpha 32 \ --lora_dropout_p 0.05 \ --lora_target_modules ALL \ --gradient_checkpointing true \ --batch_size 1 \ --weight_decay 0.01 \ --learning_rate 1e-4 \ --gradient_accumulation_steps 16 \ --max_grad_norm 0.5 \ --warmup_ratio 0.1 \ --eval_steps 100 \ --save_steps 100 \ --save_total_limit 2 \ --logging_steps 10如果你有自己的数据加两个参数指向本地文件即可--custom_train_dataset_path xxx.jsonl \ --custom_val_dataset_path yyy.jsonl微调后推理把ckpt_dir换成训练生成的 checkpoint 目录CUDA_VISIBLE_DEVICES0 \ swift infer \ --ckpt_dir output/gemma-2b-instruct/vx_xxx/checkpoint-xxx \ --load_dataset_config true \ --max_length 2048 \ --max_new_tokens 2048 \ --temperature 0.1 \ --top_p 0.7 \ --repetition_penalty 1. \ --do_sample true接下来是把请求切到 TaoToken 统一通道。用 OpenAI SDK 的话配置如下from openai import OpenAI client OpenAI( base_urlhttps://taotoken.net/api, api_key你的_TAOTOKEN_KEY ) resp client.chat.completions.create( model填入文档中的模型ID, messages[{role: user, content: hello.}], max_tokens256 ) print(resp.choices[0].message.content)如果你用 Cline 或 Claude Code 这类工具配置项要写全三件套Base URL 填https://taotoken.net/apiKey 填你的 TaoToken KeyModel ID 填文档里对应的模型标识。Cline 的 MCP 配置里同样遵循这个结构缺一个都会连不上。4. 验证请求与成功结果本地推理与统一 API 对比先验证本地推理。跑上面那段推理脚本正常输出会包含完整的对话模板标记类似bosstart_of_turnuser ... end_of_turn后面跟着模型生成的回答。如果你看到输出里重复了 prompt 本身说明add_generation_promptTrue没生效检查 transformers 版本是否 4.38.0。微调后的推理验证重点看分类任务的输出。训练后生成样例大概长这样[PROMPT]bosstart_of_turnuser Classification Task: Are the following responses from a human or from ChatGPT? Question: 能帮忙解决一下吗 Answer: 当然我很乐意帮助你解决问题。请提出你的问题我会尽力给出最好的帮助。 Category: Human, ChatGPT Output:end_of_turn start_of_turnmodel [OUTPUT]ChatGPTend_of_turn [LABELS]ChatGPT另一条样例里模型对「请问哪样存钱好」的回答判定为Human和标签一致。这说明 LoRA 微调后模型已经能跟上分类任务的格式要求。训练准确率曲线在 SWIFT 的日志里会按eval_steps打印你可以对照logging_steps的 loss 下降趋势判断是否收敛。再验证统一 API 通道。用上面的 OpenAI SDK 脚本发一条请求成功时resp.choices[0].message.content会返回模型输出HTTP 状态码 200。如果返回 401说明 Key 不对或没带上如果返回 404检查base_url是不是写成了https://taotoken.net/api而不是别的路径。对比微调前后效果时建议固定同一批测试样本分别用本地 checkpoint 和统一 API 通道各跑一遍把输出并排贴出来。我实测下来分类这种格式明确的任务微调后的输出稳定性明显好于 base 模型直接推理base 模型经常不按Category:的格式走。5. 本篇常见错排查401、local proxy failed 与 reading choices第一个高频报错是 401。完整信息通常是Error code: 401 - {error: {message: Invalid API key}}。原因就两个Key 复制时带了空格或者环境变量没读到。排查方法是先echo $TAOTOKEN_KEY确认值存在再检查代码里是不是写成了api_keyos.environ[TAOTOKEN_KEY]而不是硬编码。如果用的是 Cline 或 Claude Code去设置里确认 Base URL、Key、Model ID 三件套都填了缺 Model ID 也会报鉴权类错误。第二个是local proxy failed或连接超时。这类报错一般出现在请求根本没发出去的时候检查你的网络环境是否能正常访问 HTTPS 服务以及base_url有没有拼错。注意不要在任何配置里引入非标准的网络转发设置标准 HTTPS 直连即可。第三个是reading choices相关的报错典型信息是KeyError: choices或AttributeError: NoneType object has no attribute choices。这通常是因为返回体不是预期的 JSON 结构可能是请求被拦截或模型 ID 不存在。排查顺序先打印完整resp看原始返回再确认model字段填的是文档里真实存在的模型标识。如果返回体里是error字段而不是choices按 error 里的 message 定位。第四个是 OAuth 相关报错出现在 Claude Code 这类工具里信息类似OAuth token expired或authentication failed。这时候不要走 OAuth 流程改用 API Key 方式配置Base URL 填https://taotoken.net/apiKey 填 TaoToken 的 KeyModel ID 填对应标识。三件套齐全后重启工具即可。还有一个容易忽略的坑微调时--lora_target_modules ALL在 2B 模型上没问题但如果你换成 7B 且显存吃紧可以改成指定模块列表同时把--gradient_accumulation_steps调大。显存不够的报错通常是CUDA out of memory先降--batch_size到 1再开--gradient_checkpointing true。6. 从本地到统一通道Gemma 评测的持续调用方案把本地推理跑通、微调做完、统一 API 通道验证过之后你手上其实有了两套可切换的调用方式。本地适合做权重级别的实验和离线批量评测统一 API 通道适合做快速对照和持续性调用。两者用同一套 OpenAI 兼容协议代码改动量很小。如果你后面要把 Gemma 接入到日常的编码辅助或 Agent 工作流里建议把 Key 和 Base URL 统一放到环境变量或配置文件里管理不要散落在各个脚本中。需要长期、高频调用的话可以看下 Coding Planhttps://taotoken.net/coding-plan它针对持续性编码场景做了适配只是偶尔验证模型输出用模型对话入口https://taotoken.net/models就够。接入文档在https://taotoken.net/docAPI Key 管理在https://taotoken.net/api-keys遇到鉴权或模型 ID 问题先翻文档再排查能省不少时间。最后留一个实用习惯每次切换 checkpoint 或切换 API 通道做对比时固定随机种子torch.manual_seed和temperature否则输出差异里混入了采样噪声你分不清是微调带来的提升还是随机性。分类任务把temperature设到 0.1、top_p设到 0.7输出会稳定很多。