Thyme
Thyme 是一款突破传统视觉交互范式的开源 AI 模型,旨在让智能体“超越图像本身”进行思考。它不再局限于被动地识别图片内容,而是能够自主生成并执行多样化的图像处理代码与计算操作,从而主动分析高分辨率图像或解决复杂的推理难题。
这一工具主要解决了现有多模态模型在面对精细感知任务和复杂逻辑推导时能力不足的问题。通过引入创新的“监督微调 + 强化学习”两阶段训练策略,并结合独有的 GRPO-ATS 算法,Thyme 在探索推理路径与确保代码执行精度之间取得了极佳平衡,显著提升了处理高难度视觉任务的准确率。
Thyme 特别适合人工智能研究人员、大模型开发者以及需要处理复杂视觉数据分析的工程团队使用。无论是希望深入研究视觉推理机制的学者,还是致力于构建下一代具身智能或自动化分析系统的工程师,都能利用其开放的 SFT 与 RL 模型及数据集进行二次开发或评估。作为入选 ICLR 2026 的前沿成果,Thyme 为多模态领域提供了一套从数据准备、模型训练到效果评估的完整解决方案,助力社区探索视觉智能的新边界。
使用场景
某医疗影像分析团队正在处理一批高分辨率病理切片,需要从中精准计数细胞数量并计算特定区域的异常密度,以辅助医生进行癌症早期筛查。
没有 Thyme 时
- 分辨率受限导致漏检:传统多模态模型受限于上下文窗口,必须压缩输入图片,导致微小细胞特征丢失,计数准确率大幅下降。
- 缺乏精确计算能力:模型仅能给出模糊的定性描述(如“很多”或“少量”),无法执行具体的数学运算得出精确密度数值。
- 流程割裂效率低下:开发人员需先让模型识别区域,再人工编写脚本裁剪图像并调用外部库计算,环节繁琐且容易出错。
- 复杂推理易幻觉:在面对重叠细胞或复杂背景时,模型常因无法“深思”而产生幻觉,编造不存在的检测结果。
使用 Thyme 后
- 代码驱动的高清感知:Thyme 自主生成可执行代码,动态对高分辨率切片进行分块处理和放大操作,确保每一个微小细胞都被精准捕捉。
- 自动执行精确计算:模型直接编写并运行 Python 脚本完成细胞计数与密度公式运算,输出结果精确到小数点后两位,消除估算误差。
- 端到端自主闭环:从图像预处理、特征提取到最终数值计算,Thyme 在一个对话回合内自动完成所有步骤,无需人工干预中间流程。
- 深度推理抑制幻觉:借助 GRPO-ATS 算法强化的推理探索能力,Thyme 能在执行代码前规划最佳策略,有效区分重叠细胞与背景噪声。
Thyme 通过“超越图像”的代码执行能力,将多模态大模型从单纯的“看图说话”升级为能独立解决复杂视觉计算任务的专业智能体。
运行环境要求
- Linux
必需 NVIDIA GPU,需支持 flash-attn 和 deepspeed,具体显存未说明(建议大显存以运行 72B 模型及 RL 训练),CUDA 版本未明确指定但需兼容 torch 和 flash-attn
未说明

快速开始
🔥 最新消息
2025.09.04🌟 Thyme 已被 VLMEvalKit 和 LMMs-Eval 支持。欢迎随时使用!2025.08.18🌟 我们非常高兴地推出 Thyme: 超越图像的思考。Thyme 不再局限于传统的“以图像为媒介的思考”模式,而是通过可执行代码自主生成并执行多样化的图像处理与计算操作,从而显著提升在高分辨率感知和复杂推理任务上的表现。借助结合监督微调与强化学习的创新两阶段训练策略,并由新颖的 GRPO-ATS 算法赋能,Thyme 在推理探索与代码执行精度之间实现了精妙的平衡。
目录
1. 快速入门
1.1 克隆仓库
git clone https://github.com/yfzhang114/Thyme.git
cd Thyme
1.2 环境设置与依赖安装
我们建议创建一个 Conda 环境以实现隔离,并按以下步骤安装依赖:
conda create -n Thyme python=3.10 -y
conda activate Thyme
pip install -e .
pip install "sglang[all]" -U
pip install "vllm>=0.5.1" "transformers<4.55" "trl<0.21" -U
pip install "lmdeploy>=0.5,<0.9" -U --no-deps
pip install autoawq -U --no-deps
pip install auto_gptq optimum bitsandbytes "gradio<5.33" -U
pip install git+https://github.com/modelscope/ms-swift.git
pip install timm -U
pip install "deepspeed<0.17" -U
pip install qwen_vl_utils qwen_omni_utils decord librosa icecream soundfile -U
pip install liger_kernel nvitop pre-commit math_verify py-spy -U
pip install wandb
pip install flash-attn --no-build-isolation --use-pep517
2. 数据准备
2.1 下载数据集
从 HuggingFace 数据集页面 获取训练数据。SFT 数据集包含三个子集:
wo_thinking_thyme_single_round: 单轮图像操作数据2round: 多轮对话数据computation: 用于计算任务的退火数据
每个样本的 image 字段是一个列表,包含原始图像和处理后的图像。
2.2 处理图像并更新路径
在训练之前,请确保所有引用的图像均已下载并保存到本地。通过将图像 URL 或远程路径替换为本地绝对路径来更新数据文件(例如 .jsonl),例如:
"image": [
"/path/to/original_images/0904.0709_0.jpg",
"/path/to/processed_images/0904.0709_0_6349.jpg"
]
#!/usr/bin/env python3
import os, json, base64
from pathlib import Path
from concurrent.futures import ThreadPoolExecutor, as_completed
from datasets import load_dataset
from tqdm import tqdm
import io
from PIL import Image
HF_DATA_DIR = "./data/Thyme-SFT"
ROOT_OUT = Path("Thyme_sft_data")
IMG_ROOT = './data/Thyme_sft_data/img'
JSONL_ROOT = ROOT_OUT / "jsonl"
SPLITS = ["wo_thinking_thyme_single_round", "2round", "computation"] #,
MAX_WORKERS = os.cpu_count() # 可根据机器配置调整
# IMG_ROOT.mkdir(parents=True, exist_ok=True)
JSONL_ROOT.mkdir(parents=True, exist_ok=True)
# ----------- 线程池任务 -----------
def save_one_image(args):
"""
解码 Base64 字符串,处理透明度并以 JPEG 格式保存图像。
Args:
args (tuple): 包含 (b64_str, save_path) 的元组。
"""
b64_str, save_path = args
if os.path.exists(save_path):
return save_path
try:
# 1. 解码 Base64 以获取原始二进制数据
image_bytes = base64.b64decode(b64_str)
# 2. 使用 Pillow 从二进制数据打开图像
with Image.open(io.BytesIO(image_bytes)) as img:
# 3. 处理透明度(关键步骤)
# 检查图像模式是否需要处理透明度。
# 'P' 模式可能包含透明度,'LA' 是灰度+透明度。
# 'RGBA' 是最常见的带有透明度的模式。
if img.mode in ("RGBA", "LA", "P"):
# 为了统一处理所有透明度情况,首先将图像转换为 RGBA 模式。
# 如果图像是带有透明度的 'P' 模式,转换后会得到正确的 RGBA 图像。
img = img.convert("RGBA")
# 创建白色背景的基础图像
background = Image.new("RGB", img.size, (255, 255, 255))
# 将原图粘贴到背景上。
# 此时 img 已经是 RGBA 模式,因此可以作为自己的遮罩。
# Pillow 会自动使用其 Alpha 通道。
background.paste(img, (0, 0), img)
img = background # 现在 img 是合并后的 RGB 图像
# 如果图像模式不是 RGB(例如 'L', 'CMYK' 等),则将其转换为 RGB
elif img.mode != "RGB":
img = img.convert("RGB")
# 4. 以 JPEG 格式保存图像
# JPEG 不支持透明度,因此需要填充背景。
img.save(save_path, "jpeg", quality=95) # 建议添加质量参数
return str(save_path)
except Exception as e:
# 添加异常处理以便调试是哪张图像导致了问题
print(f"处理 {save_path} 的图像时出错:{e}")
return None
# ----------- 主处理 -----------
for split in SPLITS:
print(f"\n>>> 处理分片 : {split} (max_workers={MAX_WORKERS})")
# 3. 写入 jsonl 文件,检查是否已存在
jsonl_path = JSONL_ROOT / f"{split}.jsonl"
if not jsonl_path.exists(): # 只有在 jsonl 文件不存在时才写入
print(f" JSONL -> {jsonl_path}")
else:
print(f" JSONL 已存在: {jsonl_path}")
ds = load_dataset(HF_DATA_DIR, split=split)
img_dir = IMG_ROOT + '/' + split
# img_dir.mkdir(exist_ok=True)
# 1. 首先收集所有需要保存的任务
tasks = [] # (b64_str, save_path)
records = [] # 用于写入 jsonl
for sample_idx, sample in enumerate(ds):
img_paths = []
for img_idx, b64_img in enumerate(sample["image"], start=1):
img_name = f"{sample_idx+1:08d}_{img_idx:02d}.jpg"
img_path = img_dir + '/' + img_name
tasks.append((b64_img, img_path))
img_paths.append(str(img_path))
records.append({
"image": img_paths,
"question": sample["question"],
"response": sample["response"]
})
# 2. 使用多线程执行
with ThreadPoolExecutor(max_workers=MAX_WORKERS) as pool:
# 只保存尚未存在的图片
saved_images = list(tqdm(pool.map(save_one_image, tasks),
total=len(tasks), desc="保存图片"))
# 过滤掉返回 None 的项(即已经存在的文件)
saved_images = [img for img in saved_images if img is not None]
with open(jsonl_path, "w", encoding="utf-8") as f:
for rec in records:
f.write(json.dumps(rec, ensure_ascii=False) + "\n")
print(f" 图片 -> {img_dir} ({len(saved_images)} 张)")
print("\n全部完成(多线程)!")
2.3 文件路径转换以实现系统集成
在每个问题中,都包含一个需要转换为适合我们平台使用的正确系统路径的指定文件路径。以下步骤概述了处理这些路径的过程。
转换过程:
原始路径格式:
- 示例:
"用户图像路径: \"/mllm_hdd/yfzhang/data/temp_processed_images/cauldron_dvqa_images_dvqa_00110792.png_rotated_image_318.png\""
- 示例:
转换:
- 从原始路径中提取文件名。
- 将其转换为系统中
image数组的第一个元素。 - 该元素将代表系统中的正确文件路径。
响应路径转换:
- 同样地,确保在
response中提供的任何相应绝对路径都被转换为符合系统格式的形式。
- 同样地,确保在
3. 监督微调(Thyme-SFT)
3.1 训练数据格式
训练样本遵循以下 JSON 格式示例(完整数据集包含类似结构):
{
"image": ["/path/to/original.jpg", "/path/to/processed.jpg"],
"question": "<image>\n根据右上角的图表,描述 P(z) 在 z 趋近于零时的行为。选项:\n...",
"response": "思考>详细推理和可执行代码...<answer>B</answer>"
}
3.2 配置训练路径
在您的训练脚本或环境中设置以下变量:
DATASET: 您的训练数据集路径SAVE_PATH: 保存训练模型的目录Model: 您的模型路径
3.3 运行训练
执行训练脚本:
sh scripts/sft_stage1.sh # 第一阶段:监督微调
sh scripts/sft_stage2.sh # 第二阶段:计算数据退火
注意:由于计算数据包含带图和不带图的样本,这一阶段需要分别处理并输入这两种类型的数据。请确保您的脚本能够妥善处理这一点。
4. 强化学习(Thyme-RL)
4.1 RL 数据集格式
每个 RL 数据样本遵循以下结构:
{
"messages": [
{
"role": "system",
"content": "您是一位乐于助人的助手。请逐步解决问题..."
},
{
"role": "user",
"content": "<image>\n问题文本...\n"
}
],
"images": ["/path/to/image.jpg"],
"solution": "black",
"question": "穿白衬衫的男士眼镜框是什么颜色?"
}
4.2 奖励模型配置
- Believers
示例案例(采样自 MME-RealWorld-Lite 基准)
question_text = ("问题:图片中蓝色汽车的车牌号是多少?\n选项:\n" "A. S OT 911\n" "B. S TQ 119\n" "C. S QT 911\n" "D. B QT 119\n" "E. 该图片未显示车牌号。\n" "请从以上选项中选择正确答案。") image_path = "https://oss.gittoolsai.com/images/yfzhang114_Thyme_readme_22adc671318e.jpg"
<details>
<summary>所提供示例的可视化</summary>
<img src="https://oss.gittoolsai.com/images/yfzhang114_Thyme_readme_22adc671318e.jpg" alt="示例图片" width="100%">
### ❓ 用户提示
问题:图片中蓝色汽车的车牌号是多少? 选项: A. S OT 911 B. S TQ 119 C. S QT 911 D. B QT 119 E. 该图片未显示车牌号。 请从以上选项中选择正确答案。
---
### 🤖 模型响应
> \<think>为了确定图片中蓝色汽车的车牌号,我们需要重点关注位于车辆前部下方的车牌。与整辆车及图片的整体尺寸相比,车牌相对较小,因此对该区域进行放大有助于清晰地读取车牌上的字符。<br>
车牌的大致位置在车的前部下方,具体来说是图像下半部分的中央附近。通过裁剪并放大这一区域,可以提高车牌文字的可见度,从而更容易识别出正确选项。<br>
以下是用于裁剪并放大车牌区域的 Python 代码:<br>
> \<code>
```python
import cv2
import os
import numpy as np
from uuid import uuid4
# 加载图片
image_path = "/https://oss.gittoolsai.com/images/yfzhang114_Thyme_readme_22adc671318e.jpg"
image = cv2.imread(image_path)
# 定义车牌区域的坐标(根据图片内容推断)
x1, y1, x2, y2 = 1250, 1030, 1360, 1070
# 根据定义的坐标裁剪图片
cropped_image = image[y1:y2, x1:x2]
# 应用缩放因子以增强裁剪后的区域
zoom_factor = 2
resized_image = cv2.resize(cropped_image, None, fx=zoom_factor, fy=zoom_factor, interpolation=cv2.INTER_CUBIC)
# 使用随机后缀保存处理后的图片
random_suffix = str(uuid4())[:8]
processed_filename = f"17127_{random_suffix}.jpg"
processed_path = os.path.join("/mnt/data/temp_processed_images/", processed_filename)
cv2.imwrite(processed_path, resized_image)
# 打印保存的裁剪图片路径,以便进一步处理
print(processed_path)
</code>
<sandbox_output>
</sandbox_output>
通过观察裁剪并放大的车牌图片,可以清楚地看到车牌上的字符为“S QT 911”。这与选项 C 完全一致。因此,正确答案是 C. S QT 911。</think>br>
<answer> C. S QT 911 </answer>
引用
如果您在研究或应用中发现 Thyme 有用,请引用我们的论文:
@article{zhang2025thyme,
title={Thyme: Think Beyond Images},
author={Zhang, Yi-Fan and Lu, Xingyu and Yin, Shukang and Fu, Chaoyou and Chen, Wei and Hu, Xiao and Wen, Bin and Jiang, Kaiyu and Liu, Changyi and Zhang, Tianke and others},
journal={arXiv preprint arXiv:2508.11630},
year={2025}
}
相关项目
探索我们团队的其他相关工作:
常见问题
相似工具推荐
openclaw
OpenClaw 是一款专为个人打造的本地化 AI 助手,旨在让你在自己的设备上拥有完全可控的智能伙伴。它打破了传统 AI 助手局限于特定网页或应用的束缚,能够直接接入你日常使用的各类通讯渠道,包括微信、WhatsApp、Telegram、Discord、iMessage 等数十种平台。无论你在哪个聊天软件中发送消息,OpenClaw 都能即时响应,甚至支持在 macOS、iOS 和 Android 设备上进行语音交互,并提供实时的画布渲染功能供你操控。 这款工具主要解决了用户对数据隐私、响应速度以及“始终在线”体验的需求。通过将 AI 部署在本地,用户无需依赖云端服务即可享受快速、私密的智能辅助,真正实现了“你的数据,你做主”。其独特的技术亮点在于强大的网关架构,将控制平面与核心助手分离,确保跨平台通信的流畅性与扩展性。 OpenClaw 非常适合希望构建个性化工作流的技术爱好者、开发者,以及注重隐私保护且不愿被单一生态绑定的普通用户。只要具备基础的终端操作能力(支持 macOS、Linux 及 Windows WSL2),即可通过简单的命令行引导完成部署。如果你渴望拥有一个懂你
stable-diffusion-webui
stable-diffusion-webui 是一个基于 Gradio 构建的网页版操作界面,旨在让用户能够轻松地在本地运行和使用强大的 Stable Diffusion 图像生成模型。它解决了原始模型依赖命令行、操作门槛高且功能分散的痛点,将复杂的 AI 绘图流程整合进一个直观易用的图形化平台。 无论是希望快速上手的普通创作者、需要精细控制画面细节的设计师,还是想要深入探索模型潜力的开发者与研究人员,都能从中获益。其核心亮点在于极高的功能丰富度:不仅支持文生图、图生图、局部重绘(Inpainting)和外绘(Outpainting)等基础模式,还独创了注意力机制调整、提示词矩阵、负向提示词以及“高清修复”等高级功能。此外,它内置了 GFPGAN 和 CodeFormer 等人脸修复工具,支持多种神经网络放大算法,并允许用户通过插件系统无限扩展能力。即使是显存有限的设备,stable-diffusion-webui 也提供了相应的优化选项,让高质量的 AI 艺术创作变得触手可及。
everything-claude-code
everything-claude-code 是一套专为 AI 编程助手(如 Claude Code、Codex、Cursor 等)打造的高性能优化系统。它不仅仅是一组配置文件,而是一个经过长期实战打磨的完整框架,旨在解决 AI 代理在实际开发中面临的效率低下、记忆丢失、安全隐患及缺乏持续学习能力等核心痛点。 通过引入技能模块化、直觉增强、记忆持久化机制以及内置的安全扫描功能,everything-claude-code 能显著提升 AI 在复杂任务中的表现,帮助开发者构建更稳定、更智能的生产级 AI 代理。其独特的“研究优先”开发理念和针对 Token 消耗的优化策略,使得模型响应更快、成本更低,同时有效防御潜在的攻击向量。 这套工具特别适合软件开发者、AI 研究人员以及希望深度定制 AI 工作流的技术团队使用。无论您是在构建大型代码库,还是需要 AI 协助进行安全审计与自动化测试,everything-claude-code 都能提供强大的底层支持。作为一个曾荣获 Anthropic 黑客大奖的开源项目,它融合了多语言支持与丰富的实战钩子(hooks),让 AI 真正成长为懂上
ComfyUI
ComfyUI 是一款功能强大且高度模块化的视觉 AI 引擎,专为设计和执行复杂的 Stable Diffusion 图像生成流程而打造。它摒弃了传统的代码编写模式,采用直观的节点式流程图界面,让用户通过连接不同的功能模块即可构建个性化的生成管线。 这一设计巧妙解决了高级 AI 绘图工作流配置复杂、灵活性不足的痛点。用户无需具备编程背景,也能自由组合模型、调整参数并实时预览效果,轻松实现从基础文生图到多步骤高清修复等各类复杂任务。ComfyUI 拥有极佳的兼容性,不仅支持 Windows、macOS 和 Linux 全平台,还广泛适配 NVIDIA、AMD、Intel 及苹果 Silicon 等多种硬件架构,并率先支持 SDXL、Flux、SD3 等前沿模型。 无论是希望深入探索算法潜力的研究人员和开发者,还是追求极致创作自由度的设计师与资深 AI 绘画爱好者,ComfyUI 都能提供强大的支持。其独特的模块化架构允许社区不断扩展新功能,使其成为当前最灵活、生态最丰富的开源扩散模型工具之一,帮助用户将创意高效转化为现实。
LLMs-from-scratch
LLMs-from-scratch 是一个基于 PyTorch 的开源教育项目,旨在引导用户从零开始一步步构建一个类似 ChatGPT 的大型语言模型(LLM)。它不仅是同名技术著作的官方代码库,更提供了一套完整的实践方案,涵盖模型开发、预训练及微调的全过程。 该项目主要解决了大模型领域“黑盒化”的学习痛点。许多开发者虽能调用现成模型,却难以深入理解其内部架构与训练机制。通过亲手编写每一行核心代码,用户能够透彻掌握 Transformer 架构、注意力机制等关键原理,从而真正理解大模型是如何“思考”的。此外,项目还包含了加载大型预训练权重进行微调的代码,帮助用户将理论知识延伸至实际应用。 LLMs-from-scratch 特别适合希望深入底层原理的 AI 开发者、研究人员以及计算机专业的学生。对于不满足于仅使用 API,而是渴望探究模型构建细节的技术人员而言,这是极佳的学习资源。其独特的技术亮点在于“循序渐进”的教学设计:将复杂的系统工程拆解为清晰的步骤,配合详细的图表与示例,让构建一个虽小但功能完备的大模型变得触手可及。无论你是想夯实理论基础,还是为未来研发更大规模的模型做准备
Deep-Live-Cam
Deep-Live-Cam 是一款专注于实时换脸与视频生成的开源工具,用户仅需一张静态照片,即可通过“一键操作”实现摄像头画面的即时变脸或制作深度伪造视频。它有效解决了传统换脸技术流程繁琐、对硬件配置要求极高以及难以实时预览的痛点,让高质量的数字内容创作变得触手可及。 这款工具不仅适合开发者和技术研究人员探索算法边界,更因其极简的操作逻辑(仅需三步:选脸、选摄像头、启动),广泛适用于普通用户、内容创作者、设计师及直播主播。无论是为了动画角色定制、服装展示模特替换,还是制作趣味短视频和直播互动,Deep-Live-Cam 都能提供流畅的支持。 其核心技术亮点在于强大的实时处理能力,支持口型遮罩(Mouth Mask)以保留使用者原始的嘴部动作,确保表情自然精准;同时具备“人脸映射”功能,可同时对画面中的多个主体应用不同面孔。此外,项目内置了严格的内容安全过滤机制,自动拦截涉及裸露、暴力等不当素材,并倡导用户在获得授权及明确标注的前提下合规使用,体现了技术发展与伦理责任的平衡。
</sandbox_output>