添加seedance2.5
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
"""给 Seedance-2.5 补齐能力与定价元数据。
|
||||
|
||||
这条模型已经在生产库里(后台加的),但 metadata 装的是 Seedance-2.0 的能力
|
||||
(durations 只到 15),而且缺 pricing —— 缺 pricing 会让 get_token_price 直接抛
|
||||
ValueError,每次提交都失败;durations 停在 15 则拿不到「支持 30 秒」这个信息。
|
||||
视频复刻(商品 / 角色)固定走这一档,两样都必须是对的。
|
||||
|
||||
覆盖策略分两类:
|
||||
- 能力事实(modes / durations / resolutions / capabilities / routing / audio)**强制覆盖** ——
|
||||
它们描述模型本身能做什么,不是运营偏好。留着 2.0 抄过来的 15 秒会让 30 秒静默失效。
|
||||
- 运营可调项(pricing / watermark / source)只在缺失时填 —— 后台改过的价目不能被迁移冲掉。
|
||||
|
||||
⚠️ pricing 暂用 Seedance-2.0 标准档数字占位,火山 2.5 官方价目待核对(见 catalog.py 注释)。
|
||||
幂等:可重复 apply。
|
||||
"""
|
||||
from django.db import migrations
|
||||
|
||||
NAME = "doubao-seedance-2-5-260628"
|
||||
DURATIONS = list(range(4, 31))
|
||||
RESOLUTIONS = ["480p", "720p", "1080p", "4k"]
|
||||
MODES = ["text", "startFrameOptional", "imageReference:9", "videoReference:3", "audioReference:3"]
|
||||
|
||||
# 与 apps/ai/catalog.py 的 Seedance-2.5 条目逐键对齐(那边由 _enrich_catalog_routing 自动生成)
|
||||
CAPABILITY_FACTS = {
|
||||
"audio": "optional",
|
||||
"modes": MODES,
|
||||
"durations": DURATIONS,
|
||||
"resolutions": RESOLUTIONS,
|
||||
"routing": {"fallback_on_failure": False, "fallback_candidate": True},
|
||||
"capabilities": {
|
||||
"operations": ["video_generate"],
|
||||
"features": [
|
||||
"text_to_video", "start_frame", "image_reference",
|
||||
"video_reference", "audio_reference", "generate_audio",
|
||||
],
|
||||
"max_reference_images": 9,
|
||||
"max_reference_videos": 3,
|
||||
"max_reference_audios": 3,
|
||||
"aspect_ratios": ["21:9", "16:9", "4:3", "1:1", "3:4", "9:16"],
|
||||
"resolutions": RESOLUTIONS,
|
||||
"durations": DURATIONS,
|
||||
},
|
||||
}
|
||||
|
||||
OPERATOR_TUNABLE = {
|
||||
"watermark": False,
|
||||
"source": "volcengine ark · Seedance 2.5",
|
||||
"pricing": {
|
||||
"unit": "cny_per_million_tokens",
|
||||
"default": {"no_ref_video": 46, "with_ref_video": 28},
|
||||
"1080p": {"no_ref_video": 51, "with_ref_video": 31},
|
||||
"4k": {"no_ref_video": 26, "with_ref_video": 16},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def seed(apps, schema_editor):
|
||||
ModelProvider = apps.get_model("ai", "ModelProvider")
|
||||
ModelConfig = apps.get_model("ai", "ModelConfig")
|
||||
|
||||
provider, _ = ModelProvider.objects.get_or_create(
|
||||
name="volcengine",
|
||||
defaults={
|
||||
"display_name": "火山引擎(豆包)",
|
||||
"status": "active",
|
||||
"base_url": "https://ark.cn-beijing.volces.com/api/v3",
|
||||
},
|
||||
)
|
||||
# 生产库里这行已存在,只修元数据;其它环境(测试 / 全新部署)则建出来。
|
||||
# created_at 晚于现有视频模型 → get_default_model(VIDEO) 仍取原默认,主流程零影响。
|
||||
ModelConfig.objects.get_or_create(
|
||||
provider=provider,
|
||||
name=NAME,
|
||||
capability="video",
|
||||
defaults={
|
||||
"display_name": "Seedance-2.5",
|
||||
"endpoint": "contents/generations/tasks",
|
||||
"status": "active",
|
||||
"is_default": False,
|
||||
"metadata": {**OPERATOR_TUNABLE, **CAPABILITY_FACTS},
|
||||
},
|
||||
)
|
||||
for config in ModelConfig.objects.filter(name=NAME, capability="video"):
|
||||
metadata = dict(config.metadata or {})
|
||||
for key, value in OPERATOR_TUNABLE.items():
|
||||
metadata.setdefault(key, value)
|
||||
metadata.update(CAPABILITY_FACTS) # 能力事实强制纠正
|
||||
config.metadata = metadata
|
||||
if not config.endpoint:
|
||||
config.endpoint = "contents/generations/tasks"
|
||||
config.save(update_fields=["metadata", "endpoint", "updated_at"])
|
||||
|
||||
|
||||
def noop(apps, schema_editor):
|
||||
"""只补元数据,回滚不删 —— 删了会让在途任务计价失败。"""
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [("ai", "0032_drop_storyboard_prompt_template")]
|
||||
operations = [migrations.RunPython(seed, noop)]
|
||||
Reference in New Issue
Block a user