Auto-Research

Auto-Research

Twinkle Auto 是一个基于终端的智能训练助手,支持通过自然语言控制、监控和调试 ML 训练。它将聊天驱动的 AI 代理与自动化健康监控器相结合,能够自主检测并修复训练故障。

架构概览

┌──────────────────────────────────────────────────────────┐
│ TwinkleAuto (asyncio 聊天循环)                            │
│                                                          │
│ 核心组件:                                                 │
│   AgentLoop  ─── LLM 工具调用循环                         │
│   TrainingMonitor ─── 定期健康检查与自动修复               │
│   LocalConnection ─── 基于文件系统的通信层                 │
│   SkillManager ─── 异步插件加载                           │
└──────────────────────────────────────────────────────────┘

安装与启动

Auto 是 twinkle-client 包的一部分:

pip install twinkle-client

命令行用法

# 基本启动(使用默认本地 Ollama 端点)
twinkle-auto

# 指定 LLM 后端
twinkle-auto --llm-base-url http://localhost:11434/v1 --llm-model qwen3.5

# 连接到已有训练运行
twinkle-auto --run-id my-grpo-run

# 使用远程 API(如 OpenAI 兼容接口)
twinkle-auto --llm-base-url https://api.example.com/v1 --llm-api-key sk-xxx --llm-model gpt-4o

# 启用调试日志
twinkle-auto --verbose

也可作为 Python 模块运行:

python -m twinkle_client.auto

CLI 参数

参数环境变量默认值说明
--run-id, -rTWINKLE_AUTO_RUN_IDNone连接到已有训练运行
--llm-base-urlTWINKLE_LLM_BASE_URLhttp://localhost:11434/v1LLM API 基础 URL
--llm-modelTWINKLE_LLM_MODELqwen3.5LLM 模型名称
--llm-api-keyTWINKLE_LLM_API_KEYnot-neededLLM API 密钥
--verbose, -vTWINKLE_AUTO_VERBOSEFalse启用 DEBUG 日志
--version, -V显示版本并退出

聊天代理

Auto 的核心是一个 LLM 驱动的工具调用代理AgentLoop),通过 OpenAI 兼容 API 处理自然语言命令。代理维护对话历史并自动修剪(保留最近 50 条消息),每次交互最多支持 10 轮工具调用。

你可以这样说

训练生命周期:

  • “列出我的训练运行”
  • “用 Qwen3.5-4B 在 gsm8k 上启动一个新的 GRPO 训练”
  • “暂停当前运行”
  • “恢复训练”
  • “停止训练”

服务器管理:

  • “启动服务器,使用 Qwen3.5-4B 和一个 2 卡的 Qwen3.5-72B 采样器”
  • “关闭服务器”
  • “有多少 GPU 可用?”

监控与分析:

  • “训练进展如何?”
  • “显示 reward 相关的指标”
  • “放大到 step 100-200”
  • “重置图表视图”

搜索:

  • “搜索数学数据集”
  • “在 ModelScope 上查找 Qwen 模型”

可用工具

代理内置 13 个工具:

工具说明
list_training_runs列出所有训练运行
get_training_status获取详细状态和最近指标
start_server启动 Ray 集群 + Twinkle Server(幂等)
shutdown_server关闭服务器并释放 GPU 资源
start_training创建并启动新的训练运行
select_run切换监控到另一个运行
pause_training暂停训练(SIGKILL,服务器保留状态)
resume_training通过重新启动客户端脚本恢复训练
stop_training停止训练(SIGTERM,保存检查点)
update_script更新训练脚本(带版本归档)
list_supported_models查询服务器支持的模型
search_datasets在 ModelScope 搜索数据集
search_models在 ModelScope 搜索模型
zoom_metrics调整指标图表视图范围
select_metrics选择显示哪些指标(最多 4 个)
get_cluster_info获取 GPU/集群资源信息

服务器启动

start_server 工具自动化一个多步骤流程:

  1. GPU 检测nvidia-smi 硬件扫描
  2. GPU 分配 — 在训练模型和采样器之间分配 GPU
  3. 配置生成 — 自动创建 server_config.yaml
  4. Ray 集群启动 — 多节点 GPU 分区,隔离 CUDA_VISIBLE_DEVICES
  5. 服务器启动 — 作为后台进程启动 Twinkle Server
  6. 健康检查 — 轮询 /api/v1/healthz 直到就绪

支持多模型拓扑:1 个训练模型 + N 个采样器/教师模型。

Skills 系统

Auto 支持从三个来源加载可扩展的技能插件:

  1. 内置技能 — 包含在 twinkle_client/skills/bundled/
  2. 用户本地技能~/.cache/twinkle/auto/skills/local/
  3. 社区技能 — 从 ModelScope 获取(尽力而为,10 秒超时)

技能在启动后异步加载并注入代理的系统提示词中。代理在技能加载完成前即可使用。

训练监控器(自动修复)

TrainingMonitor 是一个后台服务,每 30 秒运行一次,收集当前训练运行的所有可用信号,并提交给 LLM 进行分析。

收集的信号

  • 进程状态:alive / dead / unknown
  • output.log 尾部:最后 1500 个字符(优先提取 traceback)
  • 指标:最近条目 + 前半段 vs 后半段趋势分析
  • 停滞时长:自最后一次产生指标以来的秒数
  • 当前 train.py:完整脚本源码(用于精确修复)

决策框架

LLM 将每次检查分类为三种操作之一:

决策触发条件执行动作
LGTM训练正常推进无操作
WARNINGLoss 平台期、reward hacking、KL 爆炸等向用户报告观察结果
FIX脚本崩溃、进程死亡并有 traceback自动修复并重启

自动修复流程

当需要 FIX 时:

  1. LLM 输出诊断 + 完整修复脚本
  2. 监控器将旧 train.py 归档为 train_v{N}.py
  3. 将修复脚本写为新的 train.py
  4. 通过 resume_training 重新启动训练
  5. 重置停滞追踪

安全保障:

  • 每个运行最多 3 次自动修复尝试(防止无限重试循环)
  • 修复尝试按 run_id 追踪
  • 快照去重避免对未变化状态的重复分析

基于文件的连接层

Auto 通过本地文件系统与训练进程通信:

~/.cache/twinkle/{run_id}/
├── meta.json       — 运行元数据(model_id、config、status、pid)
├── metrics.jsonl   — 每步一个 JSON 对象(增量)
├── output.log      — 训练的 stdout+stderr 合并输出
├── train.py        — 当前活动训练脚本
└── train_v{N}.py   — 归档的历史脚本版本

训练控制模型

在 Server 模式下,Twinkle Server 将所有模型/优化器状态保留在 GPU 内存中:

  • 暂停 = 杀死客户端进程 (SIGKILL) — 服务器状态保留
  • 恢复 = 重新启动客户端脚本 — 无缝继续训练
  • 停止 = SIGTERM — 触发检查点保存后退出
  • 关闭服务器 = 释放 GPU 资源,销毁模型状态

TrainingRuntime(脚本集成)

训练脚本使用 TrainingRuntime 与 Auto 集成:

from twinkle_client.auto.runtime import TrainingRuntime

rt = TrainingRuntime(run_id='my-grpo-run')
rt.start(model_id='Qwen/Qwen3.5-4B', config={'lr': 1e-5})
rt.register_graceful_shutdown(model, dataloader)

for step, batch in enumerate(dataloader):
    # ... 训练逻辑 ...
    rt.log_metrics(step=step, loss=loss, reward=reward, grad_norm=gn, lr=lr)
    rt.log(f'Completed step {step}, loss={loss:.4f}')

rt.finish()

核心方法

方法说明
start(model_id, config, script_path)初始化运行目录和元数据
log_metrics(**kwargs)metrics.jsonl 写入指标条目
log(message)打印日志消息(被捕获为 output.log
get_resume_info()获取 last_step 用于从检查点恢复
finish(status)标记训练完成,关闭文件
register_graceful_shutdown(model, dataloader)注册 SIGTERM 处理器以保存检查点

断点续训支持

TrainingRuntime 自动将训练进度保存到 meta.json(每 5 秒节流写入一次)。脚本可以使用 get_resume_info() 从上次保存的步数恢复:

rt = TrainingRuntime(run_id='my-run')
resume = rt.get_resume_info()
global_step = resume['last_step']

if global_step > 0:
    dataloader.skip_consumed_samples(global_step * BATCH_SIZE)
    print(f'从 step {global_step} 恢复训练')

优雅关停

调用 register_graceful_shutdown() 后,会安装一个 SIGTERM 处理器:

  1. 保存模型检查点(LoRA 权重 + 优化器状态)
  2. 保存数据加载器位置(consumed_train_samples
  3. 记录检查点路径
  4. 标记训练为 stopped 并退出

日志记录

所有日志写入 ./auto.log(当前工作目录):

  • 5MB 时轮转,保留 3 个备份
  • 无控制台输出 — 所有输出写入日志文件
  • 使用 --verbose 启用 DEBUG 级别日志
docs