Vertex AI 비디오 생성

Vertex AI 비디오 생성 (Veo)

Vertex AI의 Veo 비디오 생성 모델을 LiteLLM에서 통합 OpenAI 비디오 API로 사용하는 방법을 알아봐요.

출처: 문서

본문

속성 내용
설명 Google Cloud Vertex AI Veo 비디오 생성 모델
LiteLLM 라우트 vertex_ai/
지원 모델 veo-2.0-generate-001, veo-3.0-generate-preview, veo-3.0-fast-generate-preview, veo-3.1-generate-preview, veo-3.1-fast-generate-preview, veo-3.1-lite-generate-001
Cost Tracking ✅ Google이 가격을 매기는 곳(Veo 3.1 Lite)에서 720p·1080p 티어가 있는 기간 기반 가격
Logging Support ✅ 전체 요청/응답 로깅
Proxy Server Support ✅ 가상 키를 포함한 완전한 proxy 통합
Spend Management ✅ 예산 추적과 레이트 리밋
공식 문서 Vertex AI Veo Documentation ↗

빠른 시작

필요 환경 설정

import json
import os

os.environ["VERTEXAI_PROJECT"] = "your-gcp-project-id"
os.environ["VERTEXAI_LOCATION"] = "us-central1"

# Option 1: Point to a service account file
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "/path/to/service_account.json"

# Option 2: Store the service account JSON directly
with open("/path/to/service_account.json", "r", encoding="utf-8") as f:
    os.environ["VERTEXAI_CREDENTIALS"] = f.read()

기본 사용법

from litellm import video_generation, video_status, video_content
import json
import os
import time

with open("/path/to/service_account.json", "r", encoding="utf-8") as f:
    vertex_credentials = f.read()

response = video_generation(
    model="vertex_ai/veo-3.0-generate-preview",
    prompt="A cat playing with a ball of yarn in a sunny garden",
    vertex_project="your-gcp-project-id",
    vertex_location="us-central1",
    vertex_credentials=vertex_credentials,
    seconds="8",
    size="1280x720",
)

print(f"Video ID: {response.id}")
print(f"Initial Status: {response.status}")

# Poll for completion
while True:
    status = video_status(
        video_id=response.id,
        vertex_project="your-gcp-project-id",
        vertex_location="us-central1",
        vertex_credentials=vertex_credentials,
    )

    print(f"Current Status: {status.status}")

    if status.status == "completed":
        break
    if status.status == "failed":
        raise RuntimeError("Video generation failed")

    time.sleep(10)

# Download the rendered video
video_bytes = video_content(
    video_id=response.id,
    vertex_project="your-gcp-project-id",
    vertex_location="us-central1",
    vertex_credentials=vertex_credentials,
)

with open("generated_video.mp4", "wb") as f:
    f.write(video_bytes)

지원 모델

모델명 설명 최대 길이 상태
veo-2.0-generate-001 Veo 2.0 비디오 생성 5초 GA
veo-3.0-generate-preview Veo 3.0 고품질 8초 Preview
veo-3.0-fast-generate-preview Veo 3.0 빠른 생성 8초 Preview
veo-3.1-generate-preview Veo 3.1 고품질 10초 Preview
veo-3.1-fast-generate-preview Veo 3.1 빠른 10초 Preview
veo-3.1-lite-generate-001 Veo 3.1 Lite, 최저 비용 티어, 720p 또는 1080p 출력 8초 Preview

Veo 3.1 Lite는 출력 1초당 720p $0.05, 1080p $0.08로 과금되고, 요청이 1080p를 요구하지 않으면 Veo는 720p로 렌더링해요. OpenAI size 파라미터로 1080p를 요청하는 방법은 Size to Resolution Mapping을 참고해요.

비디오 생성 파라미터

LiteLLM은 OpenAI 스타일 파라미터를 Veo의 API 형태로 자동 변환해요:

OpenAI 파라미터 Vertex AI 파라미터 설명 예시
prompt instances[].prompt 비디오의 텍스트 설명 "A cat playing"
size parameters.aspectRatio, + parameters.resolution (1080p 가격 티어가 있는 모델) 16:9 또는 9:16로, 해상도별 가격이 매겨진 모델에선 720p 또는 1080p로 변환 "1920x1080" → 16:91080p
seconds parameters.durationSeconds 클립 길이(초) "8" → 8
input_reference instances[].image 애니메이션용 참조 이미지 open("image.jpg", "rb")
제공사 전용 파라미터 extra_body Vertex API로 전달 {"negativePrompt": "blurry"}

크기를 가로세로 비율로 매핑

  • 1280x720, 1920x108016:9
  • 720x1280, 1080x19209:16
  • 알 수 없는 크기는 기본 16:9

크기를 해상도로 매핑

Veo는 가로세로 비율이 아니라 자체 resolution 파라미터에서 출력 해상도를 고르므로, aspectRatio만 설정한 1920x1080 요청은 여전히 720p로 나와요. LiteLLM 가격이 별도의 1080p 요금을 갖는 모델(현재 veo-3.1-lite-generate-001)의 경우 LiteLLM도 size에서 resolution을 추론해요:

size 전송되는 aspectRatio 전송되는 resolution
1280x720 16:9 720p
720x1280 9:16 720p
1920x1080 16:9 1080p
1080x1920 9:16 1080p

그 외 size 값은 가로세로 비율로만 매핑되고 해상도는 Veo 기본값에 맡겨요. 1080p 가격 티어가 없는 모델(Veo 2.0, Veo 3.0, 기타 Veo 3.1 변형)은 추론된 resolution을 절대 받지 않으므로 요청이 변경되지 않아요. resolution을 직접 전달하면(최상위 파라미터 또는 extra_body 안), 언제나 size에서 추론된 값보다 우선해요.

curl --location 'http://0.0.0.0:4000/v1/videos' \
--header 'Content-Type: application/json' \
--header "Authorization: Bearer ***" \
--data '{
  "model": "veo-3.1-lite-generate-001",
  "prompt": "A slow aerial shot of a lighthouse at sunrise",
  "seconds": "8",
  "size": "1920x1080"
}'

응답 usage는 요청된 해상도를 보고하고, 스펜드 로그는 해당 티어로 클립을 가격으로 매겨요:

{"duration_seconds": 8.0, "video_resolution": "1080p"}

따라서 8초 Veo 3.1 Lite 클립은 1280x720에서 $0.40, 1920x1080에서 $0.64예요.

비동기 사용법

from litellm import avideo_generation, avideo_status, avideo_content
import asyncio
import json

with open("/path/to/service_account.json", "r", encoding="utf-8") as f:
    vertex_credentials = f.read()

async def workflow():
    response = await avideo_generation(
        model="vertex_ai/veo-3.1-generate-preview",
        prompt="Slow motion water droplets splashing into a pool",
        seconds="10",
        vertex_project="your-gcp-project-id",
        vertex_location="us-central1",
        vertex_credentials=vertex_credentials,
    )

    while True:
        status = await avideo_status(
            video_id=response.id,
            vertex_project="your-gcp-project-id",
            vertex_location="us-central1",
            vertex_credentials=vertex_credentials,
        )

        if status.status == "completed":
            break
        if status.status == "failed":
            raise RuntimeError("Video generation failed")

        await asyncio.sleep(10)

    video_bytes = await avideo_content(
        video_id=response.id,
        vertex_project="your-gcp-project-id",
        vertex_location="us-central1",
        vertex_credentials=vertex_credentials,
    )

    with open("veo_water.mp4", "wb") as f:
        f.write(video_bytes)

asyncio.run(workflow())

LiteLLM Proxy 사용법

config.yaml에 Veo 모델 추가:

model_list:
  - model_name: veo-3
    litellm_params:
      model: vertex_ai/veo-3.0-generate-preview
      vertex_project: os.environ/VERTEXAI_PROJECT
      vertex_location: os.environ/VERTEXAI_LOCATION
      vertex_credentials: os.environ/VERTEXAI_CREDENTIALS

Proxy 시작 후 요청:

# Step 1: Generate video
curl --location 'http://0.0.0.0:4000/videos' \
--header 'Content-Type: application/json' \
--header "Authorization: Bearer ***" \
--data '{
  "model": "veo-3",
  "prompt": "Aerial shot over a futuristic city at sunrise",
  "seconds": "8"
}'

# Step 2: Poll status
curl --location 'http://localhost:4000/v1/videos/{video_id}' \
--header 'x-litellm-api-key: ***'

# Step 3: Download video
curl --location 'http://localhost:4000/v1/videos/{video_id}/content' \
--header 'x-litellm-api-key: *** ' \
--output video.mp4
import litellm

litellm.api_base = "http://0.0.0.0:4000"
litellm.api_key = "sk-"

response = litellm.video_generation(
    model="veo-3",
    prompt="Aerial shot over a futuristic city at sunrise",
)

status = litellm.video_status(video_id=response.id)
while status.status not in ["completed", "failed"]:
    status = litellm.video_status(video_id=response.id)

if status.status == "completed":
    content = litellm.video_content(video_id=response.id)
    with open("veo_city.mp4", "wb") as f:
        f.write(content)

비용 추적

LiteLLM은 Veo가 반환한 길이를 기록하므로 기간 기반 가격을 적용할 수 있어요.

with open("/path/to/service_account.json", "r", encoding="utf-8") as f:
    vertex_credentials = f.read()

response = video_generation(
    model="vertex_ai/veo-2.0-generate-001",
    prompt="Flowers blooming in fast forward",
    seconds="5",
    vertex_project="your-gcp-project-id",
    vertex_location="us-central1",
    vertex_credentials=vertex_credentials,
)

print(response.usage)  # {"duration_seconds": 5.0}

해상도별 가격이 매겨진 모델의 경우 usagevideo_resolution(720p 또는 1080p)을 담고, 비용은 해당 티어의 초당 요금을 사용해요.

문제 해결

  • vertex_project is required: VERTEXAI_PROJECT env var를 설정하거나 요청에서 vertex_project를 전달해요.
  • Permission denied: 서비스 계정에 Vertex AI User 역할이 있고 올바른 리전이 활성화되어 있는지 확인해요.
  • 비디오가 processing에 고정: Veo 연산은 장시간 실행돼요. 10–15초마다 최대 ~10분까지 계속 폴링하세요.

더 알아보기 (Learn more)

  • OpenAI 비디오 생성
  • Azure 비디오 생성
  • Gemini 비디오 생성
  • 비디오 생성 API 레퍼런스