tutorial6 분 읽기

MiniMax H3 API로 구축하는 자동 이미지-투-비디오(R2V) 파이프라인

MiniMax H3로 자동 Reference-to-Video 파이프라인을 만드는 엔지니어링 튜토리얼. 첫 프레임 입력, 자산 스테이징, 제한 시간 있는 작업 폴링, ToAPIs 프론트엔드의 현재 요청 계약을 다룹니다.

ToAPIs Engineering & Evaluation Team
TL;DR - 핵심 요약
  • MiniMax H3의 프레임 모드 R2V는 first_frame_image(선택적으로 last_frame_image)로 클립을 고정합니다. 두 필드 모두 최대 한 장의 리스트입니다.
  • 같은 요청에서 첫/끝 프레임 입력을 reference_images, reference_videos, reference_audio와 섞지 마세요.
  • 안정적인 워커는 접근 가능한 자산을 스테이징하고 POST /v1/videos/generations를 제출한 뒤, 한도 있는 지수 백오프로 작업 상태 엔드포인트를 폴링합니다.
  • 무인 실행 전에 업로드 형식, 응답 형태, 현재 계정 요금을 확인하세요. 이 글은 지연 시간이나 가격 벤치마크가 아닙니다.

MiniMax H3 API로 구축하는 자동 이미지-투-비디오(R2V) 파이프라인

대상 모델: minimax-h3
추론 엔드포인트: https://api.toapis.com/v1/videos/generations
관련 글: MiniMax H3 API 가이드 · 카메라 워크 프롬프트 · H3와 Turbo 선택


1. 핵심 요약 및 개요 (TL;DR)

  • 목표: MiniMax H3 프레임 모드로 정지 이미지를 짧은 클립으로 만든 뒤, 제출과 폴링을 무인 실행 가능한 워커로 감쌉니다.
  • 입력: 한 원소 리스트인 first_frame_image, 선택적 한 원소 리스트 last_frame_image, 그 앵커에서 떠나거나 주위를 도는 움직임을 설명하는 프롬프트, 기본 minimax-h3에서는 정수 4–15초.
  • 모드: 프레임 입력과 참조 미디어는 배타적입니다. Turbo(minimax-h3-max-turbo)는 참조 미디어를 거부합니다. 참조 필드를 Turbo 페이로드에 복사하지 마세요.
  • 워커: 접근 가능한 자산을 스테이징하고, POST는 한 번만 하며, 작업 식별자를 저장하고, 백오프와 하드 데드라인으로 폴링한 뒤 결과 URL을 자체 시스템에 저장합니다.
  • 범위: 현재 ToAPIs 프론트엔드 계약에 대한 통합 가이드이며 지연 시간, 가용성, 가격 벤치마크가 아닙니다.

2. 파이프라인 청사진

무인 R2V 워커는 호출자의 HTTP 요청과 오래 걸리는 렌더를 분리해야 합니다.

  1. 수신: 제품에서 온 원본 정지 이미지와 모션 프롬프트.
  2. 스테이징: 문서화된 업로드 흐름을 쓰거나, 가져올 권한이 있는 URL을 사용합니다. 비공개 디스크 경로보다 짧은 수명의 접근 가능한 로케이터를 가진 오브젝트 스토리지를 우선하세요.
  3. 제출: model, prompt, duration, first_frame_image를 담은 POST /v1/videos/generations를 한 번만 보냅니다.
  4. 폴링: 문서화된 작업 상태 엔드포인트를 한도 있는 지수 백오프와 전체 제한 시간으로 확인합니다.
  5. 전달: 결과 비디오 URL을 자체 알림 경로(큐, 이메일, 제품 웹훅)로 보냅니다. 두 번째 과금 작업을 만들기 전에 상태를 확인하세요.

정지 프레임이 게이트웨이와 폴링 고리를 거쳐 출력 프레임이 되는 추상 R2V 파이프라인

그림 1: 정지 이미지를 스테이징한 뒤 ToAPIs generations 게이트웨이에 한 번만 제출하고, 종료 상태까지 폴링한 다음 여러분의 서비스가 완성 클립을 내보냅니다.

대부분의 400은 제출 전 다음 확인으로 막을 수 있습니다.

  • 계정에 활성화된 정확한 모델 ID를 사용합니다(minimax-h3, minimax-h3-max, 또는 minimax-h3-max-turbo. 별칭을 만들지 마세요).
  • duration은 정수입니다. 기본 H3는 4–15초, Max 계열은 5–15초.
  • first_frame_image와 last_frame_image는 각각 최대 한 장의 리스트입니다.
  • 같은 요청에서 reference_images, reference_videos, reference_audio를 보내지 마세요.
  • 현재 프론트엔드는 프레임 모드에서 ratio를 adaptive로 강제합니다. 정지 이미지의 형태를 의도한 캔버스에 맞추면(와이드는 1920×1080, 세로는 1080×1920) 예상치 못한 크롭을 줄일 수 있습니다.
  • 계약 필드 이름은 ratio이며 aspect_ratio가 아닙니다.

프레임 모드에서도 카메라 문구를 쓸 수 있습니다. 카메라 워크 프롬프트 가이드를 참고하고, 대괄호 태그는 프롬프트 도우미로 다루세요.


3. 프로덕션 구현: cURL과 Python

1단계: cURL 첫 프레임 요청

bash
curl -X POST "https://api.toapis.com/v1/videos/generations" \
  -H "Authorization: Bearer $TOAPIS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "minimax-h3",
    "prompt": "[Dolly Forward] Rain falling onto neon asphalt, steam rising from grates, cinematic reflections",
    "duration": 6,
    "ratio": "16:9",
    "first_frame_image": ["https://example.com/starting-frame.jpg"]
  }'

플레이스홀더 URL을 문서화된 업로드 흐름의 자산 식별자 또는 URL로 바꾸세요. 게시된 H3 계약에서 first_frame_image는 배열이며 단일 문자열이 아닙니다.

끝 프레임도 안내하려면 같은 프레임 모드 요청에 "last_frame_image": ["https://example.com/ending-frame.jpg"]를 추가합니다. 이는 표준 프레임 모드이며 Turbo 전용 실험 플래그가 아닙니다.

2단계: 제한 시간 폴링이 있는 Python 워커

배포 전에 task_id, status, video_url을 계정 문서의 응답 스키마와 맞추세요.

python
import os
import time
import requests
from typing import Any

API_KEY = os.environ["TOAPIS_API_KEY"]
BASE_URL = "https://api.toapis.com/v1"
HEADERS = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json",
}


class MiniMaxR2VPipeline:
    def trigger_r2v(
        self,
        image_ref: str,
        prompt: str,
        duration: int = 6,
        last_frame_ref: str | None = None,
    ) -> str:
        if not 4 <= duration <= 15:
            raise ValueError("Base minimax-h3 accepts integer durations of 4-15 seconds")
        payload: dict[str, Any] = {
            "model": "minimax-h3",
            "prompt": prompt,
            "duration": duration,
            "ratio": "16:9",
            "first_frame_image": [image_ref],
        }
        if last_frame_ref:
            payload["last_frame_image"] = [last_frame_ref]
        res = requests.post(
            f"{BASE_URL}/videos/generations",
            headers=HEADERS,
            json=payload,
            timeout=30,
        )
        res.raise_for_status()
        data = res.json()
        task_id = data.get("task_id") or data.get("id")
        if not task_id:
            raise RuntimeError(f"Unexpected submission envelope: {data}")
        return task_id

    def poll_until_complete(self, task_id: str, max_timeout: int = 180) -> dict[str, Any]:
        start = time.time()
        interval = 3.0
        poll_url = f"{BASE_URL}/videos/tasks/{task_id}"
        while time.time() - start < max_timeout:
            res = requests.get(poll_url, headers=HEADERS, timeout=15)
            res.raise_for_status()
            data = res.json()
            status = data.get("status")
            if status in {"succeeded", "success"}:
                return {
                    "status": "success",
                    "task_id": task_id,
                    "video_url": data.get("video_url"),
                    "elapsed_seconds": round(time.time() - start, 2),
                }
            if status in {"failed", "error"}:
                return {
                    "status": "error",
                    "task_id": task_id,
                    "error": data.get("error", "Generation failed"),
                }
            time.sleep(interval)
            interval = min(interval * 1.1, 6.0)
        return {
            "status": "timeout",
            "task_id": task_id,
            "error": f"Exceeded {max_timeout}s; check task status before retrying",
        }


if __name__ == "__main__":
    pipeline = MiniMaxR2VPipeline()
    # Replace with an uploaded asset identifier or a URL you are authorized to fetch.
    image_ref = "https://example.com/starting-frame.jpg"
    prompt = "[Dolly Forward] Rain falling onto neon asphalt, steam rising from grates, cinematic reflections"
    task_id = pipeline.trigger_r2v(image_ref, prompt)
    print("Task:", task_id)
    print("Result:", pipeline.poll_until_complete(task_id))

타임아웃은 확인된 실패가 아닙니다. 작업 식별자를 기록하고(API 키나 비공개 미디어 URL은 기록하지 마세요), 상태를 본 뒤에 재제출을 결정하세요.


4. 오류 처리 및 상태 매트릭스

아래 분류는 진단 출발점이며 ToAPIs의 정확한 오류 코드를 보장하지 않습니다.

HTTP 상태흔한 분류권장 조치
400잘못된 필드, 도달 불가 또는 미지원 미디어, 프레임/참조 모드 혼용모델 ID, duration, 한 원소 리스트인 first_frame_image를 검증하고 참조 필드가 없는지 확인
401API 키 누락 또는 무효ToAPIs 대시보드에서 키를 교체
429속도 또는 동시성 한도지터를 더한 백오프를 쓰고 로컬에서 대기열에 넣기
5xx 또는 네트워크 타임아웃게이트웨이 또는 업스트림 일시 장애새 작업을 만들기 전에 작업 상태를 다시 읽기

WaitTime=min⁡(MaxWait,BaseInterval×2attempt)+Uniform(0,1)\text{WaitTime} = \min(\text{MaxWait}, \text{BaseInterval} \times 2^{\text{attempt}}) + \text{Uniform}(0, 1)

업로드 실패는 하드 스톱입니다. 유효한 자산 식별자 없이 생성 요청을 보내지 마세요.


5. 요금과 FinOps ROI

Estimated cost=successful output seconds×current account rate per second\text{Estimated cost} = \text{successful output seconds} \times \text{current account rate per second}

  • 날짜가 있는 계정 견적을 사용하세요. 기획 초안의 초당 단가나 SLA 비율을 운영 예측에 붙여 넣지 마세요. 요율과 실패 작업 과금은 모델과 경로에 따라 다를 수 있습니다.
  • 공식 벤더 계약에는 약정이나 선불 하한이 붙을 수 있습니다. ToAPIs 계정이 순수 사용량 과금인지, 업스트림 실패가 어떻게 청구되는지를 확인하세요.
  • 파이프라인 규율이 실질적인 FinOps 레버입니다. 샷마다 제출은 한 번, 타임아웃 시 상태 확인 후 재시도, 프롬프트 템플릿을 작업과 함께 저장, duration은 필요한 最短 클립으로 유지.
  • 1080P가 필요하면 정확한 canonical minimax-h3-max ID가 활성화되어 있는지 확인하세요. Turbo가 필요하면 minimax-h3-max-turbo를 쓰고 참조 미디어 필드는 생략하세요. 세부 사항은 선택 가이드에 있습니다.

6. 자주 묻는 질문

구조화된 FAQ는 frontmatter를 보세요. 요약: 정지 이미지를 의도한 캔버스에 맞추고, 끝 프레임 안내는 표준 프레임 모드(각 최대 한 장)이며, 비공개 경로가 아니라 문서화된 업로드 흐름을 쓰고, 이 가이드는 ToAPIs 웹훅을 가정하지 않고 폴링합니다.


7. 액션 체크리스트

  • ToAPIs Developer Portal에서 키를 발급합니다.
  • 문서화된 업로드 흐름으로 정지 이미지 한 장을 스테이징하고 cURL 첫 프레임 요청을 스모크 테스트합니다.
  • 180초 폴링 제한과 타임아웃 시 중복 제출 금지 규칙이 있는 Python 워커를 연결합니다.
  • 배치 작업 전에 H3 요청 계약과 카메라 워크 프롬프트 가이드를 다시 확인합니다.

본문에서 언급된 모델 및 API

MiniMaxVIDEO

minimax-h3

현재 요율:20.8 credits /second
MiniMaxVIDEO

minimax-h3-max

현재 요율:8 credits /second
ToAPIsAI Model

minimax-h3-max-turbo

현재 요율:실시간 요금 확인

관련 기술 블로그

tutorial4분 읽기

Seedance 2.0 Mini API 리뷰: 저비용 고처리량 비디오 생성

ByteDance Seedance 2.0 Mini 개발자 벤치마크. 약 16–20초 지연, 네이티브 720p/24fps, 초당 $0.012로 고병행 소셜·광고 파이프라인을 운영하는 방법.

TO
ToAPIs Engineering & Evaluation Team
#Seedance 2.0 Mini