You need to enable JavaScript to run this app.
文档中心
火山方舟

火山方舟

复制全文
下载 pdf
精调数据集格式
语言及多模态理解模型精调数据格式
复制全文
下载 pdf
语言及多模态理解模型精调数据格式
进行模型精调前,需要准备符合模型类别和精调方法要求的训练集与验证集。数据集采用 JSONL 格式,每行包含一个完整的 JSON 对象。​
注意​
精调 JSONL 文件绝对路径不可包含以下特殊字符:*、?、[、]。​
本文适用于以文本作为输出的语言及多模态理解模型。训练样本可以只包含文本,也可以混合使用 image_url、audio_url、video_url 等输入;同一条样本可按模型能力组合多种模态。音频输入支持 SFT、DPO、CPT,不支持 GRPO、PPO 等 RL 训练。​
支持模型​
​
模型​
版本​
输入模态​
支持特性​
SFT​
DPO​
GRPO​
精调后推理​
doubao-seed-2-0-mini​
260428(推荐)​
文本、图片;SFT、DPO、CPT 支持音频;RL 不支持音频;视频以控制台可选能力为准​
thinking:enabled、disabled、reasoning_effort;支持 Function Calling​
全量、LoRA​
全量、LoRA​
全量、LoRA​
模型单元、批量推理窗口与基础模型一致;LoRA 按 token 推理为基础模型 2 倍价格,窗口 256k,最大回答和思维链 32k​
doubao-seed-2-0-lite​
260428(推荐)​
文本、图片;SFT、DPO、CPT 支持音频;RL 不支持音频;视频以控制台可选能力为准​
thinking:enabled、disabled、reasoning_effort;支持 Function Calling​
全量、LoRA​
全量、LoRA​
全量、LoRA​
LoRA 按 token 推理为基础模型 2 倍价格,窗口 256k,最大回答和思维链 32k;其他方式以控制台为准​
​
thinking 模式详情请参见 深度思考能力支持情况,Function Calling 详情请参见Function Calling(函数调用)。​
说明​
音频输入支持范围与模型版本及训练方式有关:​
  • SFT、DPO 和 CPT 支持通过 audio_url 传入音频。​
  • GRPO、PPO 等 RL 训练不支持音频输入。​
SFT 精调​
​
语言及多模态理解模型支持多模态混排的对话数据格式,核心基于 JSONL 文件规范,在文本对话基础上扩展了图片、音频、视频 / 视频抽帧等多模态数据支持。以下是完整的格式示例、说明及字段定义。​
格式示例​
样本格式:为 JSONL 文件( JSON Lines ,轻量级文本格式,核心规则: 每一行对应一个独立的、合法的 JSON 对象 ),需确保 单个对话样本独占一行 。​
​
{"messages":[{"role":"system","content":"请描述图片中的物体及场景"},{"role":"user","content":[{"type":"image_url","image_url":{"url":"tos://bucketname/image/desk.png"}},{"type":"text","text":"这张图片里有什么?"}]},{"role":"assistant","reasoning_content":"用户让我描述图片中的物体和场景,首先看图片内容:画面中有一张木质书桌,上面放着笔记本电脑、咖啡杯和绿植,背景是白色墙壁和窗户,光线明亮。需要准确列出物体,描述场景氛围,保持简洁明了。","content":"图片中展示了一个整洁的办公场景:一张木质书桌上放置着笔记本电脑、白色咖啡杯和一盆绿色多肉植物,背景是带有窗户的白色墙壁,自然光线充足,整体氛围清新舒适。","loss_weight":1.0}],"extra":{"sample_id":"sample-001","metadata":{"source":"user"}},"thinking":{"type": "enabled"}}​
{"messages":[{"role":"user","content":[{"type":"text","text":"计算图片中物体的数量"},{"type":"image_url","image_url":{"url":"data:image/jpeg;base64,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"}},{"type":"image_url","image_url":{"url":"file:./image/books.png"}}]},{"role":"assistant","content":"图片中包含3个主要物体:1台笔记本电脑、1个咖啡杯、1盆绿植,共3个物体。"}]}​
{"messages":[{"role": "user","content": [{"type": "image_url","image_url": {"url": "file:./image/doubao_logo.jpeg"}},{"type": "text","text": "What’s in this image?"}]},{"role": "assistant","content": "It is the logo of Doubao LLM model."}]}​
{"messages":[{"role":"user","content":[{"type":"text","text":"请将这段客服通话转写为文字,并总结客户诉求。"},{"type":"audio_url","audio_url":{"url":"tos://bucketname/audio/customer_call.wav"}}]},{"role":"assistant","content":"转写:客户咨询订单配送延迟的问题,并提供了订单号。总结:客户希望确认延迟原因和预计送达时间。","loss_weight":1.0}]}​
{"messages":[{"role":"user","content":[{"type":"text","text":"请根据视频画面和声音判断这段素材是否适合用于产品介绍。"},{"type":"video_url","fps":1,"video_url":{"url":"tos://bucketname/video/product_intro.mp4"}}]},{"role":"assistant","content":"这段视频画面清晰,讲解声音完整,适合用于产品介绍。","loss_weight":1.0}]}​
​
纯文本任务示例​
仅训练纯文本任务时,也使用语言及多模态理解模型格式。将用户输入作为 text 类型内容传入,模型回复仍写入 assistant.content。​
​
{"messages":[{"role":"system","content":[{"type":"text","text":"请根据古诗内容,仅回复作者的名字。"}]},{"role":"user","content":[{"type":"text","text":"姑苏城外寒山寺,夜半钟声到客船"}]},{"role":"assistant","reasoning_content":"用户让我根据古诗内容回复作者名字,诗句是“姑苏城外寒山寺,夜半钟声到客船”。这句诗出自张继的《枫桥夜泊》。用户要求仅回复作者名字,所以直接回复。","content":"张继","loss_weight":1}]}​
{"messages":[{"role":"user","content":[{"type":"text","text":"什么时候需要 SFT?"}]},{"role":"assistant","content":"当 prompt engineering 无法稳定解决问题,或模型输出需要满足固定格式但仍有部分 case 不符合要求时,可以考虑使用 SFT。SFT 也可用于减少 prompt 中的复杂约束,降低线上推理耗时。","loss_weight":1}]}​
​
格式说明​
将 JSONL 文件中的一条数据展开,清晰展示字段层级关系:​
​
{​
"messages": [​
{​
"role": "system",​
"content": "请描述图片中的物体及场景" // 本示例中system角色使用文本内容​
},​
{​
"role": "user",​
"content": [ // user角色支持数组格式,混排文本、图片、音频、视频​
{​
"type": "image_url", // 内容类型:图片​
"image_url": {​
"url": "tos://bucketname/image/desk.png" // 图片地址(TOS/base64/相对路径)​
}​
},​
{​
"type": "text", // 内容类型:文本​
"text": "这张图片里有什么?"​
},​
{​
"type": "audio_url", // 内容类型:音频​
"audio_url": {​
"url": "tos://bucketname/audio/customer_call.wav" // 音频地址(TOS)​
}​
},​
{​
"type": "video_url", // 内容类型:视频,支持视频内嵌音频​
"fps": 1, // 视频抽帧帧率,表示每秒抽取的帧数​
"video_url": {​
"url": "tos://bucketname/video/product_intro.mp4" // 视频地址(TOS 或 Base64)​
}​
}​
]​
},​
{​
"role": "assistant",​
"reasoning_content": "用户让我描述图片中的物体和场景,首先看图片内容:画面中有一张木质书桌,上面放着笔记本电脑、咖啡杯和绿植,背景是白色墙壁和窗户,光线明亮。需要准确列出物体,描述场景氛围,保持简洁明了。",​
"content": "图片中展示了一个整洁的办公场景:一张木质书桌上放置着笔记本电脑、白色咖啡杯和一盆绿色多肉植物,背景是带有窗户的白色墙壁,自然光线充足,整体氛围清新舒适。",​
"loss_weight": 1.0 // 训练权重,默认1.0​
}​
],​
"extra": {​
"sample_id": "sample-001",​
"metadata": {​
"source": "user"​
}​
},​
"thinking": {"type": "enabled"} // 深度思考能力控制字段​
}​
​
字段说明​
每行一条 JSON 格式数据,核心字段如下:​
​
字段名​
​
​
类型​
是否必填​
说明​
messages​
​
​
list​
是​
对话列表,包含多轮角色交互​
​
role​
​
str​
是​
角色类型,支持system/user/assistant/tool 中的一个​
  • system:支持文本、图片、音频、视频混排​
  • user:支持文本、图片、音频、视频混排​
  • assistant:仅支持文本内容​
  • tool:如希望提升模型的Function Calling能力,需选择支持Function Calling训练的模型并提供包含Function Calling格式数据的训练集用于精调,格式可参考 Function Calling 样本要求​
​
content​
​
str/list​
是​
对话内容:​
  • 当role为assistant:字符串格式​
  • 当role为user/system:数组格式,支持text、image_url、audio_url、video_url子类型​
​
​
type​
str​
条件必选​
当role为user时​
子内容类型,可选text(文本)、image_url(图片)、audio_url(音频)或video_url(视频)​
​
​
text​
str​
条件必选​
type为text时​
文本内容,不能为空字符串​
​
​
image_url​
dict​
条件必选​
type为image_url时​
图片信息,包含url字段(图片地址)。​
参考:图片文件要求​
​
​
audio_url​
dict​
条件必选​
type为audio_url时​
音频信息,包含url字段(音频 TOS 地址)。​
​
​
video_url​
dict​
条件必选​
type为video_url时​
视频信息,支持 TOS 地址和 Base64,包含url字段,支持视频内嵌音频。​
​
​
fps​
float​
否​
type为video_url时​
视频抽帧帧率,表示每秒抽取的帧数。​
不填时使用模型默认抽帧策略;建议根据视频时长和任务效果按需配置​
​
loss_weight​
​
float​
否​
训练权重:​
  • 当role为system/user:loss_weight默认 0.0,不可修改​
  • 当role为assistant:loss_weight默认 1.0,取值范围 [0.0,1.0]​
​
reasoning_content​
​
str​
否​
深度思考内容, 仅允许最后一个assistant角色携带 。​
  • 如多轮对话场景训练时仅最后一轮对话携带reasoning_content,模型将学习到在中间对话轮次不进行thinking,影响模型thinking效果。​
extra​
​
​
dict​
否​
样本顶层的用户自定义扩展字段。extra中的 key 必须为 string 类型,value 类型不限制。​
thinking​
​
​
str​
否​
深度思考能力控制:​
  • 部分模型精调支持该字段,​
​
直接偏好学习(DPO)​
​
语言及多模态理解模型支持多模态混排的对话数据格式,核心基于 JSONL 文件规范,在文本对话基础上扩展了图片、音频、视频 / 视频抽帧等多模态数据支持。以下是完整的格式示例、说明及字段定义。​
数据格式支持提供多个模型回复列表,通过 score 来指定对回复的偏好。训练过程将根据 score 的大小自动生成两两对比的偏序对进行训练,注意:score 相同的两个回复不会生成相应的偏序对。​
格式示例​
样本格式:为JSONL文件( JSON Lines ,是一种轻量级的文本文件格式,核心规则 每一行对应一个独立的、合法的 JSON 对象 ),需确保 单个对话样本独占一行 ,示例如下。​
​
{"messages":[{"role":"system","content":[{"type":"text","text":"你是一名多模态质检助手,需要结合文本、图片、音频和视频判断回复质量。"}]},{"role":"user","content":[{"type":"text","text":"请根据工单截图、客服通话和处理录屏,判断哪个质检结论更准确。"},{"type":"image_url","image_url":{"url":"tos://bucketname/image/ticket.png"}},{"type":"audio_url","audio_url":{"url":"tos://bucketname/audio/customer_call.wav"}},{"type":"video_url","video_url":{"url":"tos://bucketname/video/operation_record.mp4"}}]},{"role":"assistant","choices":[{"content":"客服准确解释了配送延迟原因,并在录屏中完成了补偿流程,结论完整。","score":1.0,"lm_loss_mask":1},{"content":"客服没有解决用户问题,建议直接判定为不合格。","score":0.2,"lm_loss_mask":0}]}],"thinking":{"type":"disabled"}}​
​
格式说明​
为便于展示各个字段关系,将JSON格式文件的一条数据展开,如下:​
​
{​
"messages": [​
{​
"role": "system",​
"content": [​
{​
"type": "text",​
"text": "你是一名多模态质检助手,需要结合文本、图片、音频和视频判断回复质量。"​
}​
]​
},​
{​
"role": "user",​
"content": [​
{​
"type": "text",​
"text": "请根据工单截图、客服通话和处理录屏,判断哪个质检结论更准确。"​
},​
{​
"type": "image_url",​
"image_url": {​
"url": "tos://bucketname/image/ticket.png"​
}​
},​
{​
"type": "audio_url",​
"audio_url": {​
"url": "tos://bucketname/audio/customer_call.wav"​
}​
},​
{​
"type": "video_url",​
"video_url": {​
"url": "tos://bucketname/video/operation_record.mp4"​
}​
}​
]​
},​
{​
"role": "assistant", # 最后一个message的role必须为assistant​
"choices": [ # 可以有多个response​
{​
"content": "客服准确解释了配送延迟原因,并在录屏中完成了补偿流程,结论完整。",​
"score": 1.0, # 该response的得分​
"lm_loss_mask": 1 # 这个response是否计算 sft loss,默认为0​
},​
{​
"content": "客服没有解决用户问题,建议直接判定为不合格。",​
"score": 0.2,​
"lm_loss_mask": 0 # 这个response是否计算 sft loss,默认为0​
}​
]​
}​
],​
"thinking": {​
"type": "disabled"​
}​
}​
​
每行一条JSON格式的数据:​
​
字段名​
​
​
类型​
是否必填​
说明​
messages​
​
​
list​
是​
对话列表,包含多轮角色交互​
​
role​
​
str​
是​
角色类型,支持system/user/assistant/tool,其中:​
  • system:支持文本、图片、音频、视频混排​
  • user:支持文本、图片、音频、视频混排​
  • assistant:仅支持文本内容​
​
content​
​
str/list​
是​
非最后一轮的对话内容​
  • 当role为assistant:字符串格式​
  • 当role为system/user:数组格式,支持text、image_url、audio_url、video_url子类型​
​
​
type​
str​
是( 当role为user时)​
子内容类型,可选text(文本)、image_url(图片)、audio_url(音频)或video_url(视频)​
​
​
text​
str​
是(type=text 时)​
文本内容,不能为空字符串​
​
​
image_url​
dict​
是(type=image_url 时)​
图片信息,包含url字段(图片地址)。​
参考:图片文件要求​
​
​
audio_url​
dict​
是(type=audio_url 时)​
音频信息,包含url字段(音频 TOS 地址)。参考:音频/视频文件要求​
​
​
video_url​
dict​
是(type=video_url 时)​
视频信息,支持 TOS 地址和 Base64,包含url字段,支持视频内嵌音频。参考:音频/视频文件要求​
​
​
fps​
float​
否​
视频抽帧帧率,表示每秒抽取的帧数。仅在 type=video_url 时生效,不填时使用模型默认抽帧策略。​
​
choices​
​
list​
是​
仅可以在最后一轮对话中填写,且list长度在2~5之间​
​
​
content​
str/list​
是​
  • 字符串格式:文本内容​
  • 数组格式:仅支持type为text​
​
​
reasoning_content​
str​
否​
深度思考内容, 仅允许最后一个assistant角色携带 。​
  • 如果打开 lm_loss_mask,则需要注意将非最后一轮的 assistant 对话 loss_weight 置为 0,否则将影响模型的深度思考能力​
​
​
score​
float​
是​
偏好值,范围在0~1的浮点数,越高表示越偏好​
​
​
lm_loss_mask​
float​
是​
该条消息是否计算 sft loss,默认为 0,即不计算 sft loss; 建议将score最大的回复lm_loss_mask 设为1,如果全为0 可能导致模型训练不稳定,泛化能力变差。​
​
loss_weight​
​
float​
否​
该条 message loss 的加权系数,默认为 1​
thinking​
​
​
str​
否​
(支持该参数的模型选填,不支持的模型禁填)​
深度思考能力控制:​
​
强化学习(GRPO/PPO)​
​
语言及多模态理解模型支持多模态混排的对话数据格式,核心基于 JSONL 文件规范,在文本对话基础上扩展了图片、视频 / 视频抽帧等多模态数据支持。以下是完整的格式示例、说明及字段定义。​
注意​
GRPO、PPO 等 RL 训练不支持音频输入,数据中不得使用 audio_url。​
格式示例​
样本格式:为JSONL文件( JSON Lines ,是一种轻量级的文本文件格式,核心规则 每一行对应一个独立的、合法的 JSON 对象 ),需确保 单个对话样本独占一行 ,示例如下。​
​
{"messages": [{"role": "user","content": [{"type": "text","text": "\nLet's think step by step and output the final answer within \\boxed{}."},{"type": "image_url","image_url": {"url": "data:image/{image_extension};base64,{image_base64}"}},{"type":"video_url","video_url":{"url":"tos://bucketname/video/question.mp4"}}]}],"extra": {"answer": "A"},"thinking": {"type": "enabled"}}​
​
格式说明​
​
{​
"messages": [​
{​
"role": "user",​
"content": [​
{​
"type": "text",​
"text": "\nLet's think step by step and output the final answer within \\boxed{}."​
},​
{​
"type": "image_url",​
"image_url": {​
"url": "data:image/{image_extension};base64,{image_base64}"​
}​
},​
{​
"type": "video_url",​
"video_url": {​
"url": "tos://bucketname/video/question.mp4"​
}​
}​
]​
}​
],​
"extra": {​
"answer": "A"​
},​
"thinking": {"type": "enabled"}​
}​
​
每一条JSON格式的数据:​
​
字段名​
​
​
类型​
是否必填​
说明​
messages​
​
​
list​
是​
对话列表,包含多轮角色交互​
​
role​
​
str​
是​
角色类型,支持system/user/assistant/tool,其中:​
  • system:支持文本、图片、视频混排​
  • user:支持文本、图片、视频混排​
  • assistant:仅支持文本内容​
  • tool:如希望提升模型的Function Calling能力,需选择支持Function Calling训练的模型并提供包含Function Calling格式数据的训练集用于精调,格式可参考 Function Calling 样本要求​
  • 最后一个message的role必须是user或tool​
​
content​
​
str/list​
是​
对话内容:​
  • 当role为assistant:字符串格式​
  • 当role为system/user:数组格式,支持text、image_url、video_url子类型​
​
​
type​
str​
是( 当role为user时)​
子内容类型,可选text(文本)、image_url(图片)或video_url(视频)​
​
​
text​
str​
是(type=text 时)​
文本内容,不能为空字符串​
​
​
image_url​
dict​
是(type=image_url 时)​
图片信息,包含url字段(图片地址)。​
参考:图片文件要求​
​
​
video_url​
dict​
是(type=video_url 时)​
视频信息,支持 TOS 地址和 Base64,包含url字段,支持视频内嵌音频。参考:音频/视频文件要求​
​
​
fps​
float​
否​
视频抽帧帧率,表示每秒抽取的帧数。仅在 type=video_url 时生效,不填时使用模型默认抽帧策略。​
extra​
​
​
dict​
否​
样本顶层的用户自定义扩展字段,可用于携带 reward function 与 custom rollout 所需的信息。extra中的 key 必须为 string 类型,value 类型不限制。​
thinking​
​
​
str​
否​
(支持该参数的模型选填,不支持的模型禁填)​
深度思考能力控制:​
​
继续预训练​
​
继续预训练支持以下几类样本组织方式:​
  • 纯文本:适用于标准文本继续预训练。​
  • 分段 content[]:适用于需要显式保留内容片段边界的场景。​
  • 多模态 content[]:适用于图文、音频、视频等继续预训练样本。​
格式示例​
样本格式:为JSONL文件( JSON Lines ,是一种轻量级的文本文件格式,核心规则 每一行对应一个独立的、合法的 JSON 对象 ),需确保 单个样本独占一行 ,示例如下。​
​
{"text": "火山方舟通过稳定可靠的安全互信方案,保障模型提供方的模型安全与模型使用者的信息安全,加速大模型能力渗透到千行百业,助力模型提供方和使用者实现商业新增长。"}​
{"content":[{"type":"text","text":"支持运行超大规模的分布式任务,"},{"type":"text","text":"包含多种预置算法框架和自定义算法框架。"}]}​
{"content":[{"type":"image_url","image_url":{"url":"tos://bucketname/image/figure.jpeg"}},{"type":"text","text":"学习这张图片对应的描述方式。"}]}​
{"content":[{"image_url":{"url": "data:image\/jpeg;base64,xx"}, "type": "image_url"},{"type": "text", "text": "今天天气很好", "loss_weight": 1.0}]}​
{"content":[{"type":"audio_url","audio_url":{"url":"tos://bucketname/audio/customer_call.wav"}},{"type":"text","text":"这是一段客服通话音频,可用于学习语音转写、说话人意图识别与问题摘要的表达方式。"}]}​
{"content":[{"type":"video_url","video_url":{"url":"tos://bucketname/video/demo.mp4"}},{"type":"text","text":"学习这段视频中画面与声音的联合描述方式。"}]}​
​
​
格式说明​
为便于展示各个字段关系,将 JSONL 格式文件中的几类典型样本展开如下:​
​
{​
"text": "火山引擎机器学习平台是面向机器学习应用开发者,提供【开发机】和【自定义训练】等丰富建模工具、多框架高性能模型推理服务的企业级开发平台,支持从数据托管、代码开发、模型训练、模型部署的全生命周期工作流。"​
}​
{​
"content": [​
{​
"type": "text",​
"text": "支持运行超大规模的分布式任务,"​
},​
{​
"type": "text",​
"text": "包含多种预置算法框架和自定义算法框架。"​
}​
]​
}​
{​
"content": [​
{​
"type": "image_url",​
"image_url": {​
"url": "tos://bucketname/image/figure.jpeg"​
}​
},​
{​
"type": "text",​
"text": "学习该图片所对应的描述内容。"​
}​
]​
}​
{​
"content": [​
{​
"type": "audio_url",​
"audio_url": {​
"url": "tos://bucketname/audio/customer_call.wav"​
}​
},​
{​
"type": "text",​
"text": "这是一段客服通话音频,可用于学习语音转写、说话人意图识别与问题摘要的表达方式。"​
}​
]​
}​
{​
"content": [​
{​
"type": "video_url",​
"video_url": {​
"url": "tos://bucketname/video/demo.mp4"​
}​
},​
{​
"type": "text",​
"text": "学习这段视频中画面与声音的联合描述方式。"​
}​
]​
}​
​
每行一条JSON格式的数据:​
​
字段名​
类型​
是否必填​
说明​
text​
str​
与 content 二选一​
纯文本样本。每条样本不限制 text 长度,如果超长将自动根据模型最大支持的 token 拆成多个样本,因此样本总数可能会超过数据行数。​
content​
list​
与 text 二选一​
分段内容列表,支持文本或多模态内容混排。​
content[].type​
str​
是​
子内容类型,可选 text、image_url、audio_url、video_url。​
content[].text​
str​
type=text 时必填​
文本内容。​
content[].image_url​
dict​
type=image_url 时必填​
图片信息,包含 url 字段或者base64信息。​
content[].audio_url​
dict​
type=audio_url 时必填​
音频信息,包含 url 字段,支持 TOS 地址。​
content[].video_url​
dict​
type=video_url 时必填​
视频信息,支持 TOS 地址和 Base64,包含 url 字段,支持视频内嵌音频。​
content[].fps​
float​
否​
视频抽帧帧率,表示每秒抽取的帧数。仅在 type=video_url 时生效,不填时使用模型默认抽帧策略。​
​
说明​
继续预训练的多模态样本沿用统一的 content[] 结构:​
  • 纯文本:​
  • 分段纯文:{"content":[{"type":"text","text":"..."}, ...]}​
  • 图文:{"content":[{"type":"image_url",...},{"type":"text","text":"..."}]}​
  • 音频 / 视频:{"content":[{"type":"audio_url",...},{"type":"video_url",...},{"type":"text","text":"..."}]}​
图片文件要求​
图片格式要求​
  • 数据集文件大小 :单数据集文件大小需控制在 2G 以下。​
  • 图片规格 :单张图片大小限制在 10M 以内,长宽比要小于 200。单图最大支持 5120 tokens,若超出此数值则会被采样到最大值(图片 token = 长像素 * 宽像素 / 784)。​
  • 样本长度 :单样本长度若超过模型训练窗口会被截断,图片按单张整体截断。不同模型的窗口大小,参考 选择模型。​
  • 支持的图片格式 :参见下表。​
​
​
| **图片格式** | **文件扩展名** |内容格式 Content Type |​
|---|---|---|​
|JPEG |.jpg, .jpeg |image/jpeg |​
|PNG |.apng, .png |image/png |​
|GIF |.gif |image/gif |​
|WEBP |.webp |image/webp |​
|BMP |.bmp |image/bmp |​
|TIFF |.tiff, .tif |image/tiff |​
|ICO |.ico |image/x-icon |​
|DIB |.dib |image/bmp |​
|ICNS |.icns |image/icns |​
|SGI |.sgi |image/sgi |​
|JPEG2000 |.j2c, .j2k, .jp2, .jpc, .jpf, .jpx |image/jp2 |​
​
图片传入方式​
在视觉理解模型的数据输入中,图片的传入方式有多种,以满足不同场景的需求,以下是具体介绍。​
1.(推荐)使用 TOS 存储图片​
  1. 创建存储桶(Bucket)用于存储文件(Object),例如创建如下结构。​
创建存储桶详细步骤可见 对象存储控制台快速入门。​
​
bucketname #桶名称​
├── sample #桶内文件夹名称​
├── data.jsonl​
└── image #桶内文件夹名称​
├── xxx.png​
└── xxxx.png​
​
  1. jsonl文件中在URL内以“tos://${bucket}/${object}”的形式填入TOS对象地址。 注意,TOS URL所引用的图片需与JSONL文件处于同一个桶内 。这种格式能够加快数据处理速度、减少多角色传输所耗费的时间,进而提高训练效率。以上步骤完成后, 精调任务进行数据配置时选择 从TOS中导入方式 仅上传jsonl文件即可 。​
​
{​
"messages": [​
{​
"role": "user",​
"content": [​
{​
"type": "image_url",​
"image_url": {​
"url": "tos://bucketname/image/xxx.png"​
}​
},​
{​
"type": "text",​
"text": "What’s in this image?"​
}​
]​
},​
{​
"role": "assistant",​
"content": "It is the logo of Doubao LLM model."​
}​
]​
}​
​
2. 图片使用 base64编码​
格式示例​
将图片进行 base64 编码后填入 jsonl 文件中,需确保 单个样本独占一行 ,示例如下。您也可以 下载样例文件 参考。​
​
{"messages":[{"role":"user","content":[{"type":"text","text":"What’s in this image?"},{"type":"image_url","image_url":{"url":"data:image/jpeg;base64,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"}}]},{"role":"assistant","content":"It is the logo of Doubao LLM model."}]}​
{"messages":[{"role":"user","content":[{"type":"text","text":"What’s in this image?"},{"type":"image_url","image_url":{"url":"data:image/jpeg;base64,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"}}]},{"role":"assistant","content":"It is the logo of Doubao APP."}]}​
​
格式说明​
为便于展示各个字段关系,将JSONL格式文件的一条数据展开,如下:​
​
{​
"messages": [​
{​
"role": "user",​
"content": [​
{​
"type": "image_url",​
"image_url": {​
"url": "data:image/{image_extension};base64,{image_base64}"​
}​
},​
{​
"type": "text",​
"text": "What’s in this image?"​
}​
]​
},​
{​
"role": "assistant",​
"content": "It is a cat."​
}​
]​
}​
​
  • 支持在 user role 内混排图文,图文顺序无限制,训练按样本中的顺序进行。​
  • 支持多轮对话和单轮对话多图。​
  • text 字段不能为空字符串。​
  • 支持在创建精调任务时上传或选择多个文件或数据集, 单数据文件大小限制在 2G 以下,大文件可拆分为多个小文件 。​
附:图片编码方法​
以下是Python对图片进行 base64 编码的代码示例。​
​
import base64​
​
# 将结果填入 url 字段内​
def encode_image(image_path):​
extension = image_path.split(".")[-1]​
with open(image_path, "rb") as image_file:​
base64_image = base64.b64encode(image_file.read()).decode('utf-8')​
return f"data:image/{extension};base64,{base64_image}"​
​
3. 图片使用相对路径​
格式示例​
以下为 jsonl 文件中使用图片相对路径的格式示例。​
  1. 创建目录结构如下:​
  • ​
    vlm​
    ├── data.jsonl​
    └── image​
    ├── doubao_app_logo.jpeg​
    └── doubao_logo.jpeg​
    ​
  1. 则对应的数据示例如下:JSONL 文件中需确保 单个样本独占一行​
  • ​
    {"messages": [{"role": "user","content": [{"type": "image_url","image_url": {"url": "file:./image/doubao_logo.jpeg"}},{"type": "text","text": "What’s in this image?"}]},{"role": "assistant","content": "It is the logo of Doubao LLM model."}]}​
    ​
格式说明​
为便于展示各个字段关系,将JSONL格式文件的一条数据展开,如下:​
​
{​
"messages": [​
{​
"role": "user",​
"content": [​
{​
"type": "image_url",​
"image_url": {​
"url": "file:./image/doubao_logo.jpeg"​
}​
},​
{​
"type": "text",​
"text": "What’s in this image?"​
}​
]​
},​
{​
"role": "assistant",​
"content": "It is the logo of Doubao LLM model."​
}​
]​
}​
​
注意:这种格式仅支持文件夹内图片数量少于 1000 张,大于该规模仍建议使用 TOS 存储图片 。​
  • 具体操作:创建文件夹,将图片和对应的 jsonl 文件按照上述格式要求进行整理后放入该文件夹中。 如在控制台页面进行精调数据配置 需将创建的文件夹拖拽到上传框内 ,暂不支持点击上传框后选择文件夹。例如:上方目录结构需把vlm文件夹拖拽上传。对于 tos 数据集文件夹路径,可以在控制台直接点击选择。​
  • 支持图片和 jsonl 文件分别存放在同一文件夹中,通过相对路径在 jsonl 文件中指向图片(暂不支持绝对路径 tos url),文件夹内可包含多个 jsonl 文件,但要求 jsonl 文件位于文件夹根路径。​
视频抽帧图片序列​
视觉理解模型精调支持用户将视频抽帧为图片后,将时间戳和图片按顺序编排到训练集中。可参考 附3:对视频内容进行抽帧。​
注意​
doubao-seed-1.8 / 2.0 模型抽帧策略与doubao-seed-1.8 之前的模型有所不同,详情请参见 抽帧策略。​
格式示例​
样本格式:为JSONL文件( JSON Lines ,是一种轻量级的文本文件格式,核心规则 每一行对应一个独立的、合法的 JSON 对象 ),需确保 单个样本独占一行, 示例如下:​
​
{"messages": [{"role": "user","content": [{"type": "text","text": "你觉得这个恐怖吗?"},{"type": "text","text": "[0.0 second]"},{"type": "image_url","image_url": {"url": "base64/相对路径"}},{"type": "text","text": "[1.0 second]"},{"type": "image_url","image_url": {"url": "base64/相对路径"}},{"type": "text","text": "[2.0 second]"},{"type": "image_url","image_url": {"url": "base64/相对路径"}}]}]}​
​
为便于展示各个字段关系,将JSONL格式文件的一条数据展开,如下:​
​
{​
"messages": [​
{​
"role": "user",​
"content": [​
{​
"type": "text",​
"text": "你觉得这个恐怖吗?"​
},​
{​
"type": "text",​
"text": "[0.0 second]"​
},​
{​
"type": "image_url",​
"image_url": {​
"url": "base64/相对路径"​
}​
},​
{​
"type": "text",​
"text": "[1.0 second]"​
},​
{​
"type": "image_url",​
"image_url": {​
"url": "base64/相对路径"​
}​
},​
{​
"type": "text",​
"text": "[2.0 second]"​
},​
{​
"type": "image_url",​
"image_url": {​
"url": "base64/相对路径"​
}​
}​
]​
}​
]​
}​
​
音频/视频文件要求​
以下要求仅适用于语言及多模态理解模型的音频、视频输入。视频生成模型的输入素材限制,请参见全模态输入。​
音频文件需要先上传到 TOS 存储中,然后在 JSONL 文件的 audio_url 内填入 TOS 对象地址。视频文件沿用现有 messages[].content[] 或 content[] 多模态结构,通过 video_url 传入;如需控制视频抽帧帧率,可在 type 为 video_url 的同级对象中配置 fps 字段。通过 TOS 地址传入时,音频或视频对象需要与 JSONL 文件处于同一个桶内。​
说明​
audio_url 支持用于 SFT、DPO、CPT,不支持用于 GRPO、PPO 等 RL 训练。video_url 需要在支持视频输入的模型和训练方式中使用。详情请参见 选择模型。​
音频文件限制​
  • 支持常见音频格式,例如 WAV、MP3、M4A、AAC、OGG 等,具体以创建精调任务时的数据校验结果为准。​
  • 单个音频文件大小不超过 512 MB。​
  • 纯音频训练不做音频时长限制。​
  • 音频文件应保证可正常解码,避免空音轨、损坏文件或无法识别的编码格式。​
视频文件输入方式(视频内嵌音频文件)​
视频输入沿用现有多模态 content[] 结构:​
​
{​
"content": [​
{​
"type": "video_url",​
"fps": 1,​
"video_url": {​
"url": "tos://bucket/video/demo.mp4"​
}​
},​
{​
"type": "text",​
"text": "请你描述下视频中的人物的一系列动作。"​
}​
]​
}​
​
视频地址支持:​
  • TOS 地址:tos://bucket/video/demo.mp4​
  • Base64:data:video/mp4;base64,...​
暂不支持通过 File API 上传后,使用 file_id 或文件引用方式传入视频。​
视频文件限制​
  • 支持格式:​
  • MP4:video/mp4​
  • AVI:video/x-msvideo​
  • MOV:​
  • 通过 URL 传入视频时,对象存储请设置 Content-Type 为 video/quicktime。​
  • 通过 Base64 编码传入视频时,请使用 video/mov,即 data:video/mov;base64,<BASE64_ENCODING>。​
  • 单个视频文件大小不超过 512 MB。​
  • 视频内嵌音频经预处理后,音轨和纯音频文件使用一致的 token 计量规则。​
  • 如需使用视频内嵌音频进行训练,请确保视频文件包含可正常解码的音轨。​
具体操作 :​
  1. 创建存储桶(Bucket)用于存储文件(Object),创建存储桶详细步骤可见 对象存储控制台快速入门。例如创建如下结构:​
  • ​
    bucketname #桶名称​
    ├── sample #桶内文件夹名称​
    ├── data.jsonl​
    ├── audio #桶内文件夹名称​
    ├── xxx.wav​
    └── xxxx.mp3​
    └── video #桶内文件夹名称​
    ├── xxx.mp4​
    └── xxxx.mp4​
    ​
  1. jsonl文件中在URL内以“tos://${bucket}/${object}”的形式填入TOS对象地址,例如上方结构URL则为“tos://bucketname/audio/xxx.wav”或“tos://bucketname/video/xxx.mp4”。 注意,TOS URL所引用的音频或视频需与JSONL文件处于同一个桶内 。这种格式能够加快数据处理速度、减少多角色传输所耗费的时间,进而提高训练效率。以上步骤完成后, 精调任务进行数据配置时选择 从TOS中导入方式 仅上传jsonl文件即可 。​
  • ​
数据集 Thinking 字段处理工具​
您可以通过脚本将不含thinking的数据集转换为含thinking的数据集:​
  • 对于数据集中不含reasoning_content的样本,将thinking赋值为disabled。​
  • 含reasoning_content的样本,则赋值为enabled。​
您可下载 此脚本 对数据集进行转换,使您的数据集符合精调模型数据格式规范。​
多轮 reasoning_content 样本文件拆分​
您可参照以下脚本,将一条携带多轮reasoning_content的样本拆分为多条仅最后一轮对话携带reasoning_content的样本。​
  • 代码实现:输入一个JSONL样例文件,输出处理好的训练数据到指定文件夹。​
  • 使用示例:python main.py --input test.jsonl --output res-folder​
  • ​
    import json​
    import os​
    import argparse​
    from process import process_sample​
    from typing import List, Dict, Any​
    ​
    def process_sample(sample: Dict[str, Any]) -> List[Dict[str, Any]]:​
    """​
    处理单个样例数据,根据规则生成一组处理后的样例​
    ​
    参数:​
    sample: 包含消息的字典,格式如案例所示​
    ​
    返回:​
    处理后的样例列表​
    """​
    messages = sample["messages"]​
    ​
    # 用于存储处理后的消息​
    message_result_list = []​
    processed_messages = []​
    not_set_loss_weight_index = []​
    ​
    for i in range(0, len(messages)):​
    current = messages[i]​
    ​
    # 最后一个消息不需要处额外理​
    if i == len(messages) - 1:​
    processed_messages.append(current)​
    message_result_list.append(processed_messages.copy())​
    break​
    ​
    # 只处理role为assistant的消息​
    if current.get("role") == "assistant":​
    # 检查是否存在loss_weight: 0​
    has_loss_weight_zero = "loss_weight" in current and current["loss_weight"] == 0​
    # 检查是否存在reasoning_content​
    has_reasoning_content = "reasoning_content" in current​
    ​
    # 情况1: 不存在loss_weight:0, 且存在reasoning_content​
    if not has_loss_weight_zero and has_reasoning_content:​
    # 拆分出当前消息, 并添加到消息列表中​
    previous_messages = [msg.copy() for msg in processed_messages]​
    previous_messages.append(current.copy())​
    message_result_list.append(previous_messages.copy())​
    ​
    # 处理当前消息, 不保留reasoning_content, 并记录loss_weight:0​
    new_assistant_msg = current.copy()​
    del new_assistant_msg["reasoning_content"]​
    new_assistant_msg["loss_weight"] = 0​
    ​
    # 将处理后的消息段保存下来,用于后续使用​
    processed_messages.append(new_assistant_msg)​
    current = []​
    ​
    # 处理之前未设置loss_weight的消息,确保每条消息只被用于一次训练​
    for idx in not_set_loss_weight_index:​
    processed_messages[idx]["loss_weight"] = 0​
    not_set_loss_weight_index = []​
    ​
    # 情况2: 存在loss_weight:0​
    elif has_loss_weight_zero:​
    # 不做拆分,不保留reasoning_content​
    new_assistant_msg = current.copy()​
    if "reasoning_content" in new_assistant_msg:​
    del new_assistant_msg["reasoning_content"]​
    ​
    processed_messages.append(new_assistant_msg)​
    # 情况3: 不存在reasoning_content​
    else:​
    processed_messages.append(current)​
    # 记录下当前未设置loss_weight的消息​
    not_set_loss_weight_index.append(i)​
    else:​
    # 非assistant角色的消息直接添加​
    processed_messages.append(current)​
    ​
    # 生成最终的样例列表​
    processed_samples = []​
    for messages in message_result_list:​
    processed_sample = sample.copy()​
    processed_sample["messages"] = messages​
    processed_samples.append(processed_sample)​
    ​
    return processed_samples​
    ​
    def main():​
    parser = argparse.ArgumentParser(description='处理JSONL样例数据并输出到文件夹')​
    parser.add_argument('--input', required=True, help='输入的JSONL文件路径')​
    parser.add_argument('--output', required=True, help='输出文件夹路径')​
    ​
    args = parser.parse_args()​
    ​
    # 读取JSONL文件​
    samples = []​
    try:​
    with open(args.input, 'r', encoding='utf-8') as f:​
    for line in f:​
    if line.strip(): # 跳过空行​
    samples.append(json.loads(line))​
    except FileNotFoundError:​
    print(f"错误: 找不到输入文件 {args.input}")​
    return​
    ​
    # 处理所有样例​
    all_processed_samples = []​
    for sample in samples:​
    processed_samples = process_sample(sample)​
    all_processed_samples.extend(processed_samples)​
    ​
    # 写入JSONL文件到文件夹​
    os.makedirs(args.output, exist_ok=True)​
    ​
    try:​
    # 确保输出目录存在​
    os.makedirs(args.output, exist_ok=True)​
    ​
    # 构建完整输出路径​
    output_path = os.path.join(args.output, f"result.jsonl")​
    ​
    # 将所有样本写入JSONL文件​
    with open(output_path, 'w', encoding='utf-8') as f:​
    for sample in all_processed_samples:​
    f.write(json.dumps(sample, ensure_ascii=False) + '\n')​
    ​
    print(f"处理完成,已生成JSONL文件,包含 {len(all_processed_samples)} 个样本,保存在 {output_path}")​
    except Exception as e:​
    print(f"错误: 写入文件失败 - {e}")​
    ​
    if __name__ == "__main__":​
    main()​
    ​
对视频内容进行抽帧处理​
当您需要对视频内容进行理解时,可以对视频进行抽帧,生成若干图片后,再将图片结合文本作为提示词内容,请求视频理解的模型服务。下面是使用 Python 脚本实现的方案,供您参考。​
注意​
doubao-seed-1.8 / 2.0 模型抽帧策略与doubao-seed-1.8 之前的模型有所不同,详情请参见 抽帧策略。​
代码流程​
  1. 视频文件读取:从本地路径读取视频文件。​
  1. 对视频进行抽帧,可以支持 2 种策略:​
  1. CONSTANT_INTERVAL:固定时间间隔抽帧,如 1s 一帧,时间间隔可以调整。​
  1. EVEN_INTERVAL:固定总帧数均匀抽帧,如不管视频时长,总共抽 20 帧,抽取的总帧数可以调整。​
  1. 压缩帧图像:为了降低网络传输时延,以及减少 token 用量,将图像等比例压缩至 640*480 以内。​
  1. 请求视觉理解模型:组装请求体,包含提示词(Prompt)及所有帧图像的 Base64,并使用方舟ChatCompletion 接口调用模型服务。​
示例代码​
环境配置​
在运行脚本前,您需要配置好 API Key、获取Model ID,具体方法请参见:​
说明​
方舟平台的新用户?获取 API Key 及 开通模型等准备工作,请参见 快速入门。​
创建推理接入点时,请选择支持视觉理解的大模型,具体可参见 视觉理解能力。​
运行脚本前,请先在终端中安装依赖包。​
​
pip install opencv-contrib-python​
pip install 'volcengine-python-sdk[ark]'​
​
实现脚本以及配置​
配置您的变量,包括:​
  • <VIDEO_FILE_PATH>替换您的视频文件的路径。​
  • <MODEL>替换为模型的Model ID。​
  • prompt = "描述视频内容"配置您的文本提示,这里仅做示例使用。​
  • 选择您的抽帧策略。​
​
...​
# 1. CONSTANT_INTERVAL:固定时间间隔抽帧,可以调整时间间隔​
# 2. EVEN_INTERVAL:固定总帧数均匀抽帧,可以调整总帧数​
extraction_strategy=Strategy.CONSTANT_INTERVAL,​
# extraction_strategy=Strategy.EVEN_INTERVAL,​
...​
​
完整的 Python 脚本​
​
from typing import Optional​
# Import the OpenCV library for video processing​
import cv2​
# Import the time library for timing​
import time​
# Import the file operation library for directory deletion​
import shutil​
# Import the enum library for defining frame extraction strategies​
from enum import Enum​
​
# Import the Base64 encoding library for converting images to Base64 strings​
import base64​
# Import the operating system library for file path operations​
import os​
# Install SDK:pip install 'volcengine-python-sdk[ark]'​
from volcenginesdkarkruntime import Ark​
from volcenginesdkarkruntime._exceptions import ArkAPIError​
​
​
# Define the frame extraction strategy enumeration class​
class Strategy(Enum):​
# Fixed interval frame extraction strategy, e.g., extract one frame every 1 second​
CONSTANT_INTERVAL = "constant_interval"​
# Even interval frame extraction strategy, extract frames evenly from the entire video based on the set maximum number of frames​
EVEN_INTERVAL = "even_interval"​
​
def preprocess_video(​
video_file_path: str,​
output_dir: str,​
extraction_strategy: Optional[Strategy] = Strategy.EVEN_INTERVAL,​
interval_in_seconds: Optional[float] = 1,​
max_frames: Optional[int] = 10,​
keyframe_naming_template: str = "frame_{:04d}.jpg",​
) -> list[str]:​
"""Extract frames from video according to the specified strategy​
Args:​
video_file_path (str): Path to the video file​
output_dir (str): Output directory​
extraction_strategy (Optional[Strategy], optional): Frame extraction strategy.​
Constant interval (e.g., extract one frame every 1 second) or​
Even interval (extract frames evenly from the entire video based on the set maximum number of frames)​
Defaults to constant interval (1 frame per second).​
interval_in_seconds (Optional[float], optional): Time interval for constant interval frame extraction. Defaults to 1 second per frame.​
max_frames (Optional[int], optional): Maximum number of frames to extract. Defaults to 10 frames.​
keyframe_naming_template (_type_, optional): Naming template for extracted key frame images​
Returns:​
list[str]: List of paths to the extracted key frame images​
"""​
# Check if the output directory exists; create it if it does not​
if not os.path.exists(output_dir):​
os.makedirs(output_dir)​
# Open the video file using OpenCV​
cap = cv2.VideoCapture(video_file_path)​
# Get the frame rate of the video​
fps = cap.get(cv2.CAP_PROP_FPS)​
# Get the total number of frames in the video​
length = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))​
​
# Select the frame interval based on the strategy​
if extraction_strategy == Strategy.CONSTANT_INTERVAL:​
# Calculate the frame interval for constant interval extraction​
frame_interval = int(fps * interval_in_seconds)​
elif extraction_strategy == Strategy.EVEN_INTERVAL:​
# Calculate the frame interval for even interval extraction​
frame_interval = int(length / max_frames)​
else:​
# Throw an exception if the strategy is invalid​
raise ValueError("Invalid extraction strategy")​
# Initialize the frame counter​
frame_count = 0​
# Initialize the list of key frames​
keyframes = []​
# Loop to read video frames​
while True:​
# Read one frame​
ret, frame = cap.read()​
# Exit the loop if frame reading fails​
if not ret:​
break​
# Check if the current frame is a key frame​
if frame_count % frame_interval == 0:​
# Generate the filename for the key frame​
image_path = os.path.join(​
output_dir, keyframe_naming_template.format(len(keyframes))​
)​
# Save the key frame as an image​
cv2.imwrite(​
image_path,​
frame,​
)​
# Add the key frame path to the list​
keyframes.append(image_path)​
# Increment the frame counter​
frame_count += 1​
# Exit the loop if the maximum number of key frames is reached​
if len(keyframes) >= max_frames:​
break​
​
print("[Video Frame Extraction Completed]")​
print("[Number of Extracted Frames]", len(keyframes))​
# Return the list of key frame paths​
return keyframes​
​
def resize(image):​
"""​
Resize the image to fit the specified dimensions.​
Args:​
image (numpy.ndarray): Input image in numpy array format.​
Returns:​
numpy.ndarray: Resized image.​
"""​
# Get the original height and width of the image​
height, width = image.shape[:2]​
# Determine the target dimensions based on the image's aspect ratio​
if height < width:​
target_height, target_width = 480, 640​
else:​
target_height, target_width = 640, 480​
# Return the original image if its dimensions are already less than or equal to the target dimensions​
if height <= target_height and width <= target_width:​
return image​
# Calculate the new height and width while maintaining the image's aspect ratio​
if height / target_height < width / target_width:​
new_width = target_width​
new_height = int(height * (new_width / width))​
else:​
new_height = target_height​
new_width = int(width * (new_height / height))​
# Resize the image​
return cv2.resize(image, (new_width, new_height))​
​
# Define a method to resize the image at the specified path to an appropriate size and convert it to Base64 encoding​
def encode_image(image_path: str) -> str:​
"""​
Encode the image at the specified path​
Args:​
image_path (str): Path to the image file​
Returns:​
str: Encoded image string​
"""​
# Read the image​
image = cv2.imread(image_path)​
# Resize the image​
image_resized = resize(image)​
# Encode the image in JPEG format​
_, encoded_image = cv2.imencode(".jpg", image_resized)​
# Convert the encoded image to a Base64 string​
return base64.b64encode(encoded_image).decode("utf-8")​
​
def construct_messages(image_paths: list[str], prompt: str) -> list[dict]:​
"""​
Construct a list of messages containing text and images.​
Args:​
image_paths (list[str]): List of image file paths.​
prompt (str): Text prompt.​
Returns:​
list[dict]: List of messages containing text and images.​
"""​
print("[Assembling Request Parameters]")​
# Initialize the content list with a text message​
content = [​
{​
"type": "text",​
"text": prompt,​
},​
]​
# Iterate through the list of image paths​
for image_path in image_paths:​
# Construct an image URL message for each image path​
content.append(​
{​
"type": "image_url",​
"image_url": {​
# Convert the image to a data URL using Base64 encoding​
"url": f"data:image/jpeg;base64,{encode_image(image_path)}",​
# Specify the image detail level as low​
"detail":"low"​
},​
}​
)​
# Return the list of messages containing text and images​
return [​
{​
"role": "user",​
"content": content,​
}​
]​
​
if __name__ == "__main__":​
# Replace with the path to your video file​
video_path = "<VIDEO_FILE_PATH>"​
# API Key retrieved from environment variables; configure your API Key in advance​
ark_api_key = os.environ.get("ARK_API_KEY")​
# Replace <MODEL> with the Model ID of your model​
model_id = "<MODEL>"​
# Replace with your text prompt; this is for example use only​
prompt = "Describe the video content"​
since = time.time()​
# Delete historical frames​
if os.path.exists("videoFrames"):​
shutil.rmtree("videoFrames")​
​
selected_images = preprocess_video(​
video_file_path=video_path,​
output_dir="videoFrames",​
​
# Two frame extraction strategies​
# 1. CONSTANT_INTERVAL: Extract frames at a fixed time interval; adjust the interval as needed​
# 2. EVEN_INTERVAL: Extract a fixed total number of frames evenly; adjust the total number as needed​
extraction_strategy=Strategy.CONSTANT_INTERVAL,​
# extraction_strategy=Strategy.EVEN_INTERVAL,​
​
# Frame interval for constant interval extraction strategy​
interval_in_seconds=1,​
​
# Maximum number of frames to extract from the video​
max_frames=20​
)​
​
print("[Frame Image Compression Completed]")​
preprocess_time_cost = time.time() - since​
​
client = Ark(api_key=ark_api_key)​
since = time.time()​
try:​
response = client.chat.completions.create(​
model=model_id,​
messages=construct_messages(​
selected_images,​
prompt,​
)​
)​
​
print("[Video Understanding Result]\n", response.choices[0].message.content)​
print("\n[Total Tokens Consumed]", response.usage.total_tokens)​
print("- Input Tokens:", response.usage.prompt_tokens)​
print("- Output Tokens:", response.usage.completion_tokens)​
​
except ArkAPIError as e:​
print(e)​
​
api_time_cost = time.time() - since​
print("\n[End-to-End Total Time Consumption]", round(preprocess_time_cost + api_time_cost, 2))​
print("- Video Preprocessing Time:", round(preprocess_time_cost, 2))​
print("- Result Generation Time:", round(api_time_cost, 2))​
​
Function Calling 样本要求​
对于 Function Calling 样本,数据格式有以下几点特殊要求:​
  1. tools 字段 (必填) :您必须在样本的顶层提供 tools 字段,其格式需与推理 API 的定义保持一致。​
  1. parallel_tool_calls 字段 (可选) :这是一个布尔类型字段,默认值为 True。​
  • 它用于声明该样本是否支持并行函数调用,其含义与推理 API 中的参数一致。​
  • 如果您将此字段设为 false,但 assistant 的回复中又包含了多个 tool_calls,将会导致错误。​
  1. assistant 消息中的 tool_calls 字段 :在 messages 列表中,如果 assistant 的回复触发了函数调用,则该消息中必须包含 tool_calls 字段。​
  • tool_calls 数组中的每个 function 对象都必须包含 name 和 arguments 两个键。​
  • arguments 的值必须是一个合法的 JSON 格式字符串。​
  1. tool 角色的消息 :在 messages 列表中,用于表示函数调用返回结果的消息,其 role 必须为 tool。这类消息的 loss_weight 固定为 0.0,且不可修改。​
以下是一个包含多轮对话和并行函数调用的完整精调样本示例:​
​
{​
"messages": [​
{​
"role": "system",​
"content": "你是豆包"​
},​
{​
"role": "user",​
"content": "把北京上海的天气发给Alan"​
},​
{​
"role": "assistant",​
"content": "分别查询北京和上海的天气。",​
"tool_calls": [​
{​
"type": "function",​
"function": {​
"name": "GetCurrentWeather",​
"arguments": "{\"location\": \"北京\"}"​
}​
},​
{​
"type": "function",​
"function": {​
"name": "GetCurrentWeather",​
"arguments": "{\"location\": \"上海\"}"​
}​
}​
],​
"loss_weight": 1.0​
},​
{​
"role": "tool",​
"content": "北京天气晴,18~25°,微风"​
},​
{​
"role": "tool",​
"content": "上海天气阴,20~30°,大风"​
},​
{​
"role": "assistant",​
"content": "已经查到北京上海天气,需要发送给alan",​
"tool_calls": [​
{​
"type": "function",​
"function": {​
"name": "SendMessage",​
"arguments": "{\"receiver\": \"Alan\", \"content\": \"今天北京天气晴,18~25°,微风;上海天气阴,20~30°,大风\"}"​
}​
}​
],​
"loss_weight": 1.0​
},​
{​
"role": "tool",​
"content": "发送成功"​
},​
{​
"role": "assistant",​
"content": "已经查到北京上海今日天气,发送给了Alan",​
"loss_weight": 1.0​
}​
],​
"tools": [​
{​
"type": "function",​
"function": {​
"name": "MusicPlayer",​
"description": "歌曲查询Plugin,当用户需要搜索某个歌手或者歌曲时使用此plugin,给定歌手,歌名等特征返回相关音乐",​
"parameters": {​
"properties": {​
"artist": {​
"description": "表示歌手名字",​
"type": "string"​
},​
"description": {​
"description": "表示描述信息",​
"type": "string"​
},​
"song_name": {​
"description": "表示歌曲名字",​
"type": "string"​
}​
},​
"required": [],​
"type": "object"​
}​
}​
},​
{​
"type": "function",​
"function": {​
"name": "GetCurrentWeather",​
"description": "查询当前的天气",​
"parameters": {​
"type": "object",​
"properties": {​
"location": {​
"type": "string",​
"description": "地理位置,比如北京市"​
},​
"unit": {​
"type": "string",​
"description": "温度单位",​
"enum": [​
"celsius",​
"fahrenheit"​
]​
}​
},​
"required": [​
"location"​
]​
}​
}​
},​
{​
"type": "function",​
"function": {​
"name": "LinkReaderPlugin",​
"description": "当需要解析网页内容时,调用本插件",​
"parameters": {​
"type": "object",​
"properties": {​
"url": {​
"type": "string",​
"description": "需要解析网页链接,最多3个;"​
}​
},​
"required": [​
"url"​
]​
}​
}​
},​
{​
"type": "function",​
"function": {​
"name": "WebSearchPlugin",​
"description": "当需要搜索互联网内容时,调用本插件",​
"parameters": {​
"type": "object",​
"properties": {​
"keywords": {​
"type": "string",​
"description": "需要搜索的内容"​
}​
},​
"required": [​
"keywords"​
]​
}​
}​
},​
{​
"type": "function",​
"function": {​
"name": "SendMessage",​
"description": "需要发送微信消息时,使用本函数",​
"parameters": {​
"type": "object",​
"properties": {​
"receiver": {​
"type": "string",​
"description": "接受对象"​
},​
"content": {​
"type": "string",​
"description": "需要发送的内容"​
}​
},​
"required": [​
"receiver"​
]​
}​
}​
}​
]​
}​
​
在实际的 .jsonl 文件中,上述示例应以单行形式呈现:​
​
{"messages":[{"role":"system","content":"你是豆包"},{"role":"user","content":"把北京的天气发给Alan"},{"role":"assistant","content":"","tool_calls":[{"type":"function","function":{"name":"GetCurrentWeather","arguments":"{\"location\": \"北京\"}"}}],"loss_weight":1.0},{"role":"tool","content":"北京天气晴,18~25°,微风"},{"role":"assistant","content":"已经查到北京天气,需要发送给alan","tool_calls":[{"type":"function","function":{"name":"SendMessage","arguments":"{\"receiver\": \"Alan\", \"content\": \"今天北京天气晴,18~25°,微风\"}"}}],"loss_weight":1.0},{"role":"tool","content":"发送成功"},{"role":"assistant","content":"已经查到北京今日天气,发送给了Alan","loss_weight":1.0}],"tools":[{"type":"function","function":{"name":"MusicPlayer","description":"歌曲查询Plugin,当用户需要搜索某个歌手或者歌曲时使用此plugin,给定歌手,歌名等特征返回相关音乐","parameters":{"properties":{"artist":{"description":"表示歌手名字","type":"string"},"description":{"description":"表示描述信息","type":"string"},"song_name":{"description":"表示歌曲名字","type":"string"}},"required":[],"type":"object"}}},{"type":"function","function":{"name":"GetCurrentWeather","description":"查询当前的天气","parameters":{"type":"object","properties":{"location":{"type":"string","description":"地理位置,比如北京市"},"unit":{"type":"string","description":"温度单位","enum":["celsius","fahrenheit"]}},"required":["location"]}}},{"type":"function","function":{"name":"LinkReaderPlugin","description":"当需要解析网页内容时,调用本插件","parameters":{"type":"object","properties":{"url":{"type":"string","description":"需要解析网页链接,最多3个;"}},"required":["url"]}}},{"type":"function","function":{"name":"WebSearchPlugin","description":"当需要搜索互联网内容时,调用本插件","parameters":{"type":"object","properties":{"keywords":{"type":"string","description":"需要搜索的内容"}},"required":["keywords"]}}},{"type":"function","function":{"name":"SendMessage","description":"需要发送微信消息时,使用本函数","parameters":{"type":"object","properties":{"receiver":{"type":"string","description":"接受对象"},"content":{"type":"string","description":"需要发送的内容"}},"required":["receiver"]}}}]}​
​
注意事项​
  • tool_calls 数组中的函数调用数量,必须与后续 role 为 tool 的消息数量完全对应。​
  • 您必须遵循 JSON Schema 规范。在函数参数定义中,type 字段的值必须是以下类型之一,否则会导致错误:​
  • string​
  • number​
  • boolean​
  • integer​
  • object​
  • array​
  • 如果您希望模型在返回函数调用(fc)的同时输出思考过程(如 CoT、reasoning),请将这部分文本内容填写在 content 字段中。​
  • 如果您的训练样本不需要包含一个完整的函数调用流程,可以进行截断,但样本必须以一个 role 为 assistant 的消息结尾。​
深度思考能力支持情况​
注意​
Seed 2.0 260415 以上模型,RL 强化学习 rollout 过程的推理默认仅支持 thinking disable,不支持设置此项。​
不同模型深度思考能力可配置的枚举值不同,详细信息请参见 开启/关闭深度思考。​
​
模型版本​
enabled​
disabled​
auto​
custom​
doubao-seed-1.6|250615​
✅​
✅(default)​
✅​
❌​
doubao-seed-1.6-flash|250615​
✅​
✅(default)​
❌​
❌​
qwen​
❌​
❌​
❌​
✅(default)​
doubao-1.5-pro-32k|250115​
❌​
✅(default)​
❌​
❌​
doubao-1.5-lite-32k|250115​
❌​
✅(default)​
❌​
❌​
​
  • enabled 表示强制模型进行思考,此时模型rollout过程预期会输出reasoning_content​
  • disabled 表示强制模型不进行思考, 此时模型rollout过程预期不会输出reasoning_content。​
  • auto 表示允许模型根据问题自主判断是否需要思考,复杂问题进行思考,简单问题直接回答。​
  • custom 表示训练的数据预处理过程不就对 reasoning_content 内容做任何的校验与处理,在训练过程中,会按模型配套的 chat template 对数据进行处理。以 qwen 为例 ,样本内的 content 和 reasoning_content 会使用 https://huggingface.co/Qwen/Qwen3-32B/blob/main/tokenizer_config.json#L230 所示 chat template 逻辑进行处理。在推理时也需要使用custom type以及和训练相同的reasoning_content。​
​
最近更新时间:2026.08.11 17:02:55
这个页面对您有帮助吗?
有用
有用
无用
无用