-
t2v, i2v, flf2v, omni_reference — Seedance 2.0 fast 약어가 가리키는 것과 조합 매트릭스IT 2026. 5. 22. 21:00
📡 이 글은 BytePlus Seedance 2.0 fast 모델을 API로 직접 호출해서 영상을 만드는 사용자를 위한 글입니다. content array의 role을 직접 짜는 시나리오는 API 사용자에게만 해당됩니다. ModelArk 콘솔은 "Image-to-Video", "Reference-to-Video" 같은 UI 라벨로 task_type를 노출하므로 약어를 풀이할 일이 없습니다.
약어가 너무 많다
BytePlus Seedance API의 docs를 처음 펼치면 익숙하지 않은 약어들이 떠다닙니다. t2v, i2v, flf2v, omni_reference. 그리고 docs 어디엔가 흩어져 있는
generate_audio: true같은 옵션. 어떤 건 직관적이고, 어떤 건 풀어 봐도 의미가 잘 안 잡힙니다. 더 큰 문제는 이 task_type들이 서로 자유롭게 섞이지 않는다는 점입니다. 어떤 task_type는 어떤 모델 버전에서만 동작하고, 어떤 조합은 입력 자체를 받지 않습니다.저는 이걸 docs로만 읽고 한 번에 정리하지 못해서, 결국 몇 번의 호출이 거절되고 나서야 매트릭스를 손으로 그려 보고 이해했습니다. 다행히 거절 호출은 토큰을 안 먹으니 비용 0이었지만, 한 호출당 polling 90초가 모두 시간 비용으로 빠져나갔습니다. 이 글은 그때 만든 약어 풀이와 매트릭스를 정리한 것입니다.
약어 풀이 — 공식 task_type 이름으로
BytePlus Seedance 2.0 시리즈가 docs에서 공식적으로 노출하는 task_type은 4개입니다. 우리가 부르는 약어와 공식 이름의 매핑을 먼저 정리합니다.
약어 (관행) 공식 task_type 의미 t2v text_to_video이미지 입력 없이 prompt 텍스트만으로 영상 생성 i2v image_to_video사진 1장을 시작 프레임(first_frame)으로 두고 모델이 그 뒤 motion 생성 flf2v first_last_frames첫 프레임 + 끝 프레임 2장 → 그 사이를 보간하는 영상 생성 omni (구버전에선 r2v) omni_reference사용자가 업로드한 이미지·비디오·오디오 N개를 reference로 받아, 그 정체성·외형을 유지하면서 prompt 기반 영상 생성. 1.x 시절 reference-to-video(r2v)의 확장판으로, image뿐 아니라 video/audio reference까지 받습니다. 이 글에서는 짧은 약어와 공식 이름을 혼용합니다. 둘 다 익혀 두는 게 docs와 커뮤니티 글을 동시에 읽기 편합니다.
오디오는 task_type이 아니라 옵션입니다
오디오 동시 생성은 별도 task_type이 아니라, 위 4개 task_type 위에 얹는 두 가지 요청 파라미터의 조합입니다.
generate_audio: true— request body의 불리언 옵션. "오디오도 함께 합성하라"는 스위치.reference_audiorole의 content 요소 — 참조 음성/배경음 mp3·wav 한 개를 입력.
즉
image_to_video나omni_referencetask_type을 그대로 부르되, 위 두 가지를 같이 보내면 입 모양까지 phoneme에 맞춰 lip-sync된 영상이 떨어집니다. task_type은 바뀌지 않습니다.generate_audio: false+reference_audio는 "원본 오디오 패스스루"가 아닙니다자연스러운 오해 한 가지를 짚어두면 —
generate_audio: false로 끄고reference_audio만 같이 보내면 "오디오를 모델이 생성하지 않고 내가 올린 원본 오디오를 그대로 출력에 입혀줄 것"이라고 기대하기 쉽습니다. 실제는 다릅니다.generate_audio: false→ 출력 비디오가 무음(silent) 으로 나옵니다. 모델이 audio head를 그냥 비활성화합니다. 원본 오디오를 출력에 자동으로 입혀주는 동작은 없습니다.reference_audio→ 모델이 영상을 만들 때 참조하는 conditioning 입력입니다. 거기서 rhythm, beat, mood, lip phoneme, sound 타이밍 같은 신호를 뽑아 비디오 생성에 반영합니다. 즉 reference_audio는 출력 오디오가 아니라 입력입니다.
이 둘을 합치면 이런 결과가 나옵니다.
조합 출력 비디오 출력 오디오 트랙 활용 generate_audio: true+reference_audio없음비디오 모델이 새로 합성한 SFX·BGM·음성 일반 native audio 생성 generate_audio: true+reference_audio있음비디오 (lip-sync 움직임이 reference의 phoneme에 맞춰짐) 모델이 reference를 따라 재합성한 오디오 lip-sync 영상 한 번에 generate_audio: false+reference_audio없음비디오 무음 자체 보이스오버를 따로 입힐 작업 generate_audio: false+reference_audio있음비디오 (입 모양은 여전히 reference에 맞게 움직임) 무음 무음 비디오를 받은 뒤 ffmpeg로 원본 mp3를 직접 mux. 모델이 재합성한 음질 손실을 피하고 싶을 때 마지막 행이 실용적으로 가장 유용합니다. 인물 발화 영상을 만들 때 입 모양은 reference 음성에 맞추되 출력 오디오 트랙은 모델이 재합성한 음질 손실 버전이 아니라 원본 mp3 그대로를 쓰고 싶다면,
generate_audio: false+reference_audio로 무음 비디오를 받은 뒤 ffmpeg-c:a copy로 원본을 입힙니다. 결과적으로 "원본 오디오를 쓴다"는 효과는 달성되지만, 그건 모델이 아니라 우리가 mux한 결과입니다."role"이 뭔가요
위 표와 본문에 자꾸 등장하는 role은 BytePlus API의 정식 용어입니다. 요청의
content배열에 들어가는 각 요소에 붙는 라벨 필드로, 모델은 이 라벨을 보고 그 입력의 용도를 판단합니다. 챗 API의role: "user"/role: "assistant"와 같은 구조지만, 영상 생성에서는 이미지·오디오의 역할을 라벨링합니다.role 값 의미 first_frame영상의 시작 프레임. 모델이 이 이미지에서 출발해 motion을 만듦 last_frame영상의 끝 프레임. first와 함께 주면 그 사이를 보간 reference_image정체성 참조. 인물·소품의 외형을 새 영상 안에서도 유지하라는 hint reference_video모션/스타일 참조. 짧은 비디오 클립을 reference로 줘서 그 분위기/움직임을 따라가게 함 reference_audio오디오 참조. generate_audio: true와 함께 lip-sync·BGM 입력"role 조합"이란 한 호출의
content배열에 어떤 role의 입력을 몇 개씩 넣었는가를 말합니다. Seedance API에는 명시적인 task_type 파라미터가 없습니다. 모델은 이 role 조합을 보고 자동으로 task_type을 추론합니다. 그래서 role을 잘못 붙이면 "모르는 task_type"이 되어 거절됩니다."task_type이 결정된다"는 게 모델이 바뀐다는 뜻인가요
아닙니다. 모델은 한 개입니다. 우리가 호출하는 모델은
seedance-2.0-fast(또는seedance-1.5-pro등) 하나의 멀티모달 모델이고, 이 모델 안에서 무슨 종류의 생성 작업을 할지를 가리키는 라벨이task_type입니다. role 조합이text_to_video로 추론되면 같은 모델이 텍스트만으로 영상을 만들고,omni_reference로 추론되면 같은 모델이 reference 이미지를 따라 영상을 만듭니다. 서버 내부에서 어떤 분기 헤드가 활성화되는가의 차이일 뿐, 모델 자체는 바뀌지 않습니다.다시 말해 모델 선택 =
model파라미터에서 결정, task_type 결정 =contentrole 조합에서 자동 추론. 이 둘은 직교입니다.task_type 호환 매트릭스
이걸 한 표로 가지고 있으면 production cycle에서 시도착오가 사라집니다. 아래는 2026년 5월에 검증한 매트릭스입니다.
표의 칼럼은 모델 버전 순으로 나열했습니다 —
seedance-1.0-pro-fast(가장 오래된) →seedance-1.5-pro→seedance-2.0-fast(가장 최신). 같은 버전 내에서 pro / fast는 품질·비용 티어지만, 버전 번호가 우선입니다. 즉 2.0-fast가 1.5-pro보다 한 세대 위의 모델입니다.4개의 공식 task_type × 모델 버전
task_type (약어) role 조합 1.0-pro-fast 1.5-pro 2.0-fast text_to_video(t2v)(이미지 없음) ✅ ✅ ✅ image_to_video(i2v)first_frame × 1 ✅ ✅ ✅ first_last_frames(flf2v)first_frame + last_frame ❌ ✅ ✅ omni_reference(구 r2v / omni)reference_image × N (+ video/audio reference) ❌ ✅ ✅ generate_audio: true옵션 — 어느 task_type 위에 얹을 수 있는가오디오 동시 생성은 별도 task_type이 아닙니다. 위 4개 task_type 위에 옵션으로 얹을 수 있고, 모델 버전마다 가능 범위가 다릅니다.
범례: ✅(검증) = 직접 호출해 성공을 확인. ✅(docs) = BytePlus·플랫폼 공식 문서에 지원 명시, 직접 검증은 안 한 항목. ❓ = docs도 사용자도 확인 안 됨. ❌ = 호출 거절을 직접 확인했거나 모델 capability상 불가능한 것.
베이스 task_type + generate_audio: true1.0-pro-fast 1.5-pro 2.0-fast text_to_video❌ ❓ ✅ (docs) — 2.0 fast text-to-video 엔드포인트 docs는 generate_audio기본값이true라고 명시image_to_video❌ ❓ ✅ (검증) first_last_frames— ❓ ✅ (docs) — 2.0 docs는 native audio가 모델 전반 기능이라고 기술. 직접 검증은 안 함 omni_reference(1.5에선 r2v 이름)— ✅ (검증, 당시 r2v + audio로 호출) ✅ (검증) 특히 2.0-fast는 native audio가 task_type별 옵션이 아니라 모델 전체에 깔린 기능이라는 게 docs의 일관된 서술입니다. 그래서
text_to_video위에든omni_reference위에든generate_audio: true(또는 default true)로 호출하면 비디오와 동기화된 오디오가 같이 떨어진다고 적혀 있습니다. 제가 직접 호출해 본 건image_to_video + audio와omni_reference + audio두 가지뿐이라,text_to_video + audio/first_last_frames + audio는 docs 기준 ✅로 두되 "검증" 표시를 떼서 두 칸의 신뢰 수준을 구분했습니다.흥미로운 점은 이전 버전인 1.5-pro도 reference + audio 조합(당시 이름은 r2v + audio)을 이미 지원했다는 것입니다. 다만 1.5는 reference_video / reference_audio가 reference role의 일부로 들어가던 r2v였고, 2.0에서 이게 image+video+audio reference를 모두 받는
omni_reference로 확장됐습니다. 같은 능력이 이름만 바뀌어 살아남은 셈입니다. 1.0-pro-fast는 reference 자체를 받지 않으므로 audio도 불가능합니다. 1.5에서 t2v + audio / i2v + audio / flf2v + audio가 되는지는 docs도 사용자도 확인되지 않아 ❓로 남겨둡니다. 모델 버전과 task_type 지원이 깔끔한 누적 관계는 아니어서 매트릭스를 들고 다닐 가치가 있습니다.task_type 자동 추론을 시각화하기
다이어그램이 강조하는 건 두 가지입니다 — task_type 파라미터는 따로 없다는 것, 그리고 role 조합이 task_type을 결정한다는 것. role 하나를 잘못 붙이면 의도와 전혀 다른 task_type이 켜지고 거절됩니다.
매트릭스를 코드에 데이터로 박아두기
코드에서 task_type 분기를 if/else로 짜기 시작하면 모델이 추가될 때마다 분기가 늘어납니다. 대신 매트릭스 자체를 데이터로 두는 패턴이 진화에 강합니다. 오디오는 task_type이 아니라 옵션이므로, 별도 dict으로 둡니다.
# 공식 task_type 4개 × 모델 버전 매트릭스 SUPPORTED_TASKS: dict[tuple[str, str], bool] = { ("seedance-1.0-pro-fast", "text_to_video"): True, ("seedance-1.0-pro-fast", "image_to_video"): True, ("seedance-1.5-pro", "text_to_video"): True, ("seedance-1.5-pro", "image_to_video"): True, ("seedance-1.5-pro", "first_last_frames"): True, ("seedance-1.5-pro", "omni_reference"): True, # 1.5에서는 r2v 이름 ("seedance-2.0-fast", "text_to_video"): True, ("seedance-2.0-fast", "image_to_video"): True, ("seedance-2.0-fast", "first_last_frames"): True, ("seedance-2.0-fast", "omni_reference"): True, # 나머지는 default False } # generate_audio: true를 얹을 수 있는 (모델, task_type) 조합 SUPPORTS_AUDIO_FLAG: set[tuple[str, str]] = { ("seedance-1.5-pro", "omni_reference"), ("seedance-2.0-fast", "image_to_video"), ("seedance-2.0-fast", "omni_reference"), } def infer_task_type(content_items: list[dict]) -> str: """role 조합으로 공식 task_type 추론. 오디오 flag는 별개.""" roles = [it.get("role") for it in content_items if it["type"] == "image_url"] has_first = "first_frame" in roles has_last = "last_frame" in roles has_ref = "reference_image" in roles if has_ref: return "omni_reference" if has_first and has_last: return "first_last_frames" if has_first: return "image_to_video" return "text_to_video" def must_support(model: str, task_type: str, generate_audio: bool) -> None: if not SUPPORTED_TASKS.get((model, task_type), False): raise UnsupportedModeError(f"{model} does not support {task_type}") if generate_audio and (model, task_type) not in SUPPORTS_AUDIO_FLAG: raise UnsupportedModeError( f"{model} + {task_type}는 generate_audio:true를 받지 못합니다" )SUPPORTED_TASKS는 task_type × 모델 매트릭스,SUPPORTS_AUDIO_FLAG는 옵션 매트릭스.infer_task_type은 모델 서버가 내부에서 하는 role→task_type 추론을 클라이언트 측에서 미리 시뮬레이션합니다. 새 클립을 보내기 전에must_support(model, infer_task_type(...), generate_audio)를 한 번 호출하면 API에 보내기도 전에 클라이언트가 거절합니다. paid 호출이 polling 90초 들여 돌려준 거절 메시지를, 우리는 로컬에서 1ms만에 받습니다.결과 — 매트릭스를 들고 있을 때 달라지는 것
이 매트릭스를 들고 작업하기 시작한 뒤로는 몇 가지가 명확해졌습니다.
- 새 클립을 정의할 때 "어떤 task_type인지" 결정이 자연스럽게 첫 단계가 됩니다. task_type을 결정하면 사용할 모델 변종도 같이 좁혀집니다.
- 새 모델이 출시되면 매트릭스에 한 줄만 추가하면 됩니다. 분기 코드 수정이 필요 없습니다.
- task_type 자동 추론이 좋아도 명시적 task_type 로그는 필수입니다. 디버깅할 때 "내가 보낸 role 조합 → 모델이 추론한 task_type"를 한 줄에 보고 싶기 때문입니다.
같은 영상 1편을 두고도 클립마다 다른 task_type을 골라 쓰게 됩니다. wide shot 한 컷은
text_to_video(t2v)로 가볍게, 인물 발화 컷은omni_reference+generate_audio: true로 진하게. 모드는 사치가 아니라 production 도구상자입니다. 한 번 약어와 공식 이름을 정리하고 매트릭스를 들고 다니면, 그 도구상자가 갑자기 잘 보입니다.
이 글은 생성형 AI의 도움을 받아 작성되었습니다. 원본 자료를 기반으로 AI가 초안을 생성하고, 작성자가 검토·편집하였습니다.
'IT' 카테고리의 다른 글
Seedance 2.0 fast 영상의 첫 0.5초가 사진처럼 정지된 이유 — photo prefix 자동 제거 (0) 2026.05.23 Seedance 2.0 fast로 영상 만들 때도 reshoot이 있다 — 한 번 촬영으로 끝나지 않는 production (0) 2026.05.23 Seedance 2.0 fast API로 가족 영상 만들 때 — 토큰 영수증도 만만치 않지만, 시간이 더 비싸다 (0) 2026.05.23 프롬프트는 영화 시나리오가 아니라 체크리스트다 — Seedance 2.0 fast에서 손가락 2개와 10개의 거리 (0) 2026.05.22 Seedance 2.0 fast가 만든 영상의 입 모양이 어색했다 — lip-sync가 production 디폴트가 된 이유 (0) 2026.05.22 Seedance 2.0 fast가 실존 인물 사진을 거절했다 — 우회 말고 Real Human Asset 등록이 정도 (0) 2026.05.21 Seedance 2.0 fast는 한글 손글씨를 보존할 수 있다 — diffusion 정설을 뒤집은 prompt 4축 (0) 2026.05.21 200 OK가 거짓말을 한다 — Seedance 2.0 fast API의 silent fallback을 잡아내는 법 (0) 2026.05.21 /investigate — Trivial pass의 뿌리를 캐는 자리 (gstack 시리즈 6/6) (0) 2026.05.20 /qa — 함수가 옳아도 화면에 안 나타나는 버그를 잡는 자리 (gstack 시리즈 5/6) (0) 2026.05.20