跳到主内容
快讯直播
AI智模界
教程

GLM-5.3-Flash 改端侧决策模型:数据、微调与评测

这篇教程带你把 GLM-5.3-Flash 从通用对话模型,改造成一个能在端侧运行的结构化决策模型。完成后你会得到三样东西:一份从历史决策日志合成的 JSONL 训练集;一个 LoRA 适配器,可合并并量化成端侧引擎能加载的格式;一套离线评测脚本,输出 JSON 合法率、动作完全匹配率和动作混淆矩阵。这里的“Jev 式”指一种专用决策风格:输入当前状态,模型只输出一个结构化动作,例如点击哪个控件、输入什么内容、是否等待,而不是生成一段解释文字。

前置条件清单

  • 一张用于微调的 NVIDIA GPU。显存要求以官方文档当前版本为准,模型越大、序列越长,占用越高。
  • Python 环境,以及 PyTorch、transformers、peft、datasets、trl 或 LLaMA-Factory 等工具链。版本以官方文档当前版本为准。
  • GLM-5.3-Flash 的基座权重与 tokenizer,从官方渠道获取。
  • 至少几百到几千条历史决策日志。每条日志包含当时的状态观察、采取的动作、执行结果。
  • 一个明确的动作空间。先定 schema,再洗数据,否则后面会反复返工。
  • 端侧推理引擎,例如 llama.cpp、ONNX Runtime、MLC 或 ExecuTorch。按目标设备选。
  • 一份人工标注的 hold-out 测试集,用来做离线评测。训练集和测试集按时间切分,避免泄漏。

第 1 步:定义决策 Schema

先定义一个模型必须遵守的 JSON 结构。字段不要多,端侧解析越简单越好。

```json

{

"action": "click",

"target": "confirm_button",

"params": {},

"confidence": 0.87

}

```

动作空间可以先用枚举固定下来,例如:

```python

ACTIONS = {

"click",

"input",

"scroll",

"back",

"wait",

"finish"

}

```

target 是控件标识或语义名称,params 放输入文本、滚动方向等附加信息。confidence 可选,端侧做阈值回退时有用。AI 词典:系统提示词">系统提示词写死一句:只输出 JSON,不要解释,不要 Markdown 代码块。

第 2 步:从决策日志合成训练数据

假设原始日志是 JSONL,每行类似:

```json

{"ts":"2025-01-01T10:00:00","observation":{"screen":"order_confirm","user_intent":"确认下单"},"action":{"action":"click","target":"confirm_button","params":{}},"result":"success"}

```

先过滤失败、无效、重复的记录,再做脱敏。然后把每条日志转成指令微调样本。下面是一段可直接改路径运行的 Python:

```python

import json

from pathlib import Path

def log_to_sample(rec):

obs = rec["observation"]

act = rec["action"]

instruction = "根据当前状态输出一个 JSON 决策,不要输出其他内容。"

input_text = json.dumps(obs, ensure_ascii=False)

output_text = json.dumps(act, ensure_ascii=False)

return {"instruction": instruction, "input": input_text, "output": output_text}

samples = []

for line in Path("decision_logs.jsonl").read_text(encoding="utf-8").splitlines():

rec = json.loads(line)

if rec.get("result") != "success":

continue

samples.append(log_to_sample(rec))

n = len(samples)

train, test = samples[:int(n * 0.8)], samples[int(n * 0.8):]

Path("train.jsonl").write_text(

"\n".join(json.dumps(x, ensure_ascii=False) for x in train),

encoding="utf-8"

)

Path("test.jsonl").write_text(

"\n".join(json.dumps(x, ensure_ascii=False) for x in test),

encoding="utf-8"

)

```

只保留成功动作还不够。建议加入两类纠错样本:一是从错误决策中构造“给定同样状态,应输出正确动作”;二是格式修复样本,例如输入一段带解释的脏输出,目标输出是干净 JSON。样本量少时,纠错样本对格式稳定性的帮助通常比较明显。

第 3 步:数据校验与格式转换

训练前先校验字段,避免把脏数据喂进模型。

```python

import json

ACTIONS = {"click", "input", "scroll", "back", "wait", "finish"}

REQUIRED = {"action", "target", "params"}

def valid_decision(obj):

if not isinstance(obj, dict):

return False

if not REQUIRED.issubset(obj.keys()):

return False

if obj["action"] not in ACTIONS:

return False

if not isinstance(obj["params"], dict):

return False

return True

bad = 0

with open("train.jsonl", encoding="utf-8") as f:

for line in f:

rec = json.loads(line)

out = json.loads(rec["output"])

if not valid_decision(out):

bad += 1

print("非法样本数:", bad)

```

如果微调框架要求 ShareGPT 或 Alpaca 格式,按官方文档转换。关键点是:训练和推理必须使用同一个 chat template。模板不一致是端侧决策模型掉点的常见原因。

第 4 步:LoRA 微调

用 LLaMA-Factory 这类工具可以减少样板代码。下面是一份 YAML 配置示例,路径和模型名按你的环境替换:

```yaml

model_name_or_path: /path/to/glm-5.3-flash

stage: sft

do_train: true

finetuning_type: lora

lora_rank: 16

lora_alpha: 32

lora_dropout: 0.05

lora_target: q_proj,v_proj,k_proj,o_proj

dataset: decision_sft

template: glm

cutoff_len: 1024

per_device_train_batch_size: 2

gradient_accumulation_steps: 8

learning_rate: 1.0e-4

num_train_epochs: 3

output_dir: outputs/decision-lora

```

lora_target 要按模型实际结构填写,以官方文档当前版本为准。端侧决策任务数据量通常不大,rank 不要一上来就设很高,先跑小 rank,看验证集是否过拟合。训练时建议只对 assistant 输出部分计算 loss,输入状态部分不参与损失,这样模型更容易学会“状态进、动作出”的映射。

第 5 步:合并与量化导出

训练完成后,先把 LoRA 合并回基座。不同工具命令不同,按官方文档操作。合并后用端侧引擎支持的格式导出。以 llama.cpp 为例,通用流程是:

```bash

python convert_hf_to_gguf.py /path/to/merged-model --outfile decision-f16.gguf --outtype f16

./llama-quantize decision-f16.gguf decision-q4_k_m.gguf q4_k_m

```

具体脚本名和参数以官方仓库当前版本为准。如果目标端是 ONNX Runtime,可以用:

```bash

optimum-cli export onnx --model /path/to/merged-model --task text-generation-with-past onnx_decision/

```

导出后先别急着上端侧。先在桌面环境用同一份测试集跑一遍 fp16 和量化版本,确认掉点在可接受范围内。量化会带来精度损失,决策任务对格式敏感,需要重点看 JSON 合法率。

第 6 步:端侧推理封装

端侧推理需要一个薄封装:拼 prompt、调用模型、解析 JSON、失败回退。

```python

import json

from llama_cpp import Llama

llm = Llama(model_path="decision-q4_k_m.gguf", n_ctx=1024, n_threads=4)

SYSTEM = "你是一个端侧决策器。只输出 JSON,不要解释。"

def decide(observation: dict) -> dict:

prompt = f"{SYSTEM}\n状态:{json.dumps(observation, ensure_ascii=False)}\n决策:"

out = llm(prompt, max_tokens=128, temperature=0.0, stop=["\n\n"])

text = out["choices"][0]["text"].strip()

try:

return json.loads(text)

except json.JSONDecodeError:

start = text.find("{")

end = text.rfind("}")

if start >= 0 and end > start:

return json.loads(text[start:end + 1])

return {"action": "wait", "target": "", "params": {}}

```

温度设成 0,减少随机性。max_tokens 不要太小,否则 JSON 可能被截断。回退动作建议用“等待”或“无操作”,避免误触。

第 7 步:离线评测

评测指标至少看四个:JSON 合法率、动作完全匹配率、字段级匹配率、端侧延迟。下面是一段评测骨架:

```python

import json

from collections import Counter

def exact_match(pred, gold):

return (

pred.get("action") == gold.get("action")

and pred.get("target") == gold.get("target")

)

def evaluate(model_fn, test_path):

total = json_ok = match = 0

confusion = Counter()

with open(test_path, encoding="utf-8") as f:

for line in f:

item = json.loads(line)

gold = json.loads(item["output"])

obs = json.loads(item["input"])

total += 1

try:

pred = model_fn(obs)

json_ok += 1

except Exception:

pred = {"action": "wait", "target": ""}

if exact_match(pred, gold):

match += 1

confusion[(gold["action"], pred["action"])] += 1

print(f"JSON 合法率: {json_ok / total:.3f}")

print(f"完全匹配率: {match / total:.3f}")

for k, v in confusion.items():

print(k, v)

```

同时跑一个规则基线,例如“看到确认按钮就点击”。如果模型还不如规则基线,说明数据或 schema 有问题。再跑一次基座模型,对比微调前后的提升幅度。

常见坑与排错

  • 数据泄漏:训练集和测试集有时间重叠,指标虚高。按时间切分,不要随机切分。
  • 动作不平衡:某些动作样本极少,模型只输出多数类。可以重采样、增广,或合并长尾动作。
  • JSON 不合法:用约束解码、正则提取、重试机制;训练集里加入格式修复样本。
  • 过拟合:验证 loss 上升时早停,减小 LoRA rank,增加 dropout。
  • 量化掉点:先测 fp16,再测量化版;如果量化后掉点明显,换量化策略或保留更高精度。
  • 端侧内存不足:减小 n_ctx、缩短 prompt、降低量化位数。
  • chat template 不一致:训练和推理使用同一模板,特殊 token 要对齐。
  • 特殊 token 设置错误:确认 pad、eos、bos 与官方配置一致。

下一步建议

当单步决策稳定后,可以尝试多步决策:让模型输出动作序列,并在端侧用状态机执行。还可以引入工具调用,把“查询天气”“读取剪贴板”等能力做成结构化函数。若想进一步提升,可以用更大模型蒸馏决策数据,或者用 DPO 类方法优化偏好。最后,把线上失败样本定期回流到训练集,形成“日志—微调—评测—上线—回流”的闭环。评测脚本和 schema 建议纳入版本管理,每次模型更新都跑同一套离线评测,避免凭感觉判断好坏。

AI 生成本文由 AI 基于公开信息自动生成,仅供参考。