Veo 3.1 영상 생성 비용 줄이기, Vertex AI에서 `generateAudio: false` 적용하기

케이 (3)2026년 8월 13일
Tags #GoogleVeo

본문 초안

Google Veo 3.1 API를 사용하면서 영상 생성 비용을 줄일 방법을 찾고 있었다.

내가 원했던 건 단순했다.

영상은 필요하지만, 오디오는 필요 없다.
그럼 오디오 생성을 끄면 비용이 줄어들지 않을까?

사용 중인 SDK는 다음 패키지였다.

import { GoogleGenAI, ThinkingLevel, ApiError } from '@google/genai';

그리고 SDK 타입을 보면 generateAudio라는 파라미터가 존재한다.

generateAudio?: boolean

문제는 이 파라미터가 어떤 API 경로에서는 보이지만 실제로는 동작하지 않거나, 아예 지원되지 않는 것처럼 보인다는 점이었다.

이번 글은 그 삽질 기록이다.


결론 먼저

결론부터 말하면 다음과 같다.

| 구분 | generateAudio: false | 비용 절감 가능성 | |---|---:|---:| | Gemini Developer API | 불명확하거나 제한적 | 기대하기 어려움 | | Vertex AI / Gemini Enterprise Agent Platform | 가능 | 가능 | | 후처리로 오디오 제거 | 가능 | 비용 절감 없음 |

즉, 오디오 없는 Veo 영상을 생성해서 비용을 줄이고 싶다면 Vertex AI API 경로를 써야 했다.


처음에는 Gemini API에서 시도했다

처음에는 일반 Gemini Developer API 방식으로 호출하고 있었다.

const ai = new GoogleGenAI({
  apiKey: process.env.GEMINI_API_KEY,
});

그리고 대략 이런 식으로 Veo 영상을 생성했다.

const operation = await ai.models.generateVideos({
  model: 'veo-3.1-fast-generate-preview',
  prompt,
  config: {
    durationSeconds: 8,
    aspectRatio: '16:9',
    resolution: '720p',
    generateAudio: false,
  },
});

SDK 타입에는 generateAudio가 있었기 때문에 당연히 동작할 것이라고 생각했다.

하지만 실제로는 기대와 달랐다.

  • 에러가 나거나
  • 파라미터가 무시되는 것처럼 보이거나
  • 결과 영상에 여전히 오디오가 붙는 문제가 있었다

즉, 단순히 SDK 타입에 필드가 있다고 해서 모든 backend에서 실제 지원되는 것은 아니었다.


후처리로 오디오를 제거하는 것은 비용 절감이 아니다

처음에는 이런 방법도 생각할 수 있다.

ffmpeg -i input.mp4 -an -c:v copy output.mp4

이렇게 하면 결과 mp4에서 오디오 트랙은 제거된다.

하지만 이건 이미 생성된 영상에서 오디오를 지우는 것일 뿐이다.
Veo API 호출 시점에 이미 오디오 생성 비용이 발생했다면, 후처리로 오디오를 제거해도 API 비용은 줄지 않는다.

내가 원한 건 “결과물을 무음으로 만들기”가 아니라 “처음부터 오디오 생성을 하지 않아서 비용을 줄이기”였다.

그래서 후처리는 해결책이 아니었다.


Vertex AI 문서를 다시 확인해봤다

그러다가 Vertex AI, 현재 문서상으로는 Gemini Enterprise Agent Platform 쪽 문서를 다시 확인했다.

여기서 중요한 차이를 발견했다.

Vertex AI의 VideoGenerationModelParams 스키마에는 generateAudio가 명시되어 있다.

{
  "generateAudio": boolean
}

문서 설명도 다음과 같다.

Whether to generate audio along with the video. If true, an audio track is generated for the videos. Defaults to true.

즉 generateAudio는 boolean 값이고, 기본값은 true다. true일 때 영상에 오디오 트랙을 생성한다는 의미다.<citation refs="BkJ23myAg2ExiNRrP-kXb">generateAudio boolean: Whether to generate audio along with the video. If true, an audio track is generated for the videos. Defaults to true.</citation>

그리고 더 중요한 점은 가격표였다.

Vertex AI / Agent Platform 가격표에는 Veo 3.1이 다음처럼 나뉘어 있었다.

| 모델 | Video + Audio | Video only | |---|---:|---:| | Veo 3.1 Standard 720p/1080p | $0.40/sec | $0.20/sec | | Veo 3.1 Fast 720p | $0.10/sec | $0.08/sec | | Veo 3.1 Lite 720p | $0.05/sec | $0.03/sec |

즉 Vertex AI 쪽에서는 Video + Audio generation과 Video generation이 별도 가격으로 분리되어 있다.<citation refs="XsGdReJTdBPDYBjIWjyym">Veo 3.1: Video + Audio generation $0.40/second, Video generation $0.20/second; Veo 3.1 Fast: Video + Audio generation $0.10/second at 720p, Video generation $0.08/second at 720p; Veo 3.1 Lite: Video + Audio generation $0.05/second at 720p, Video generation $0.03/second at 720p.</citation>

이걸 보고 나서야 “아, 이건 Gemini Developer API가 아니라 Vertex AI API 경로로 가야 하는 문제구나”라고 정리됐다.


Vertex AI로 호출 방식 변경

일반 Gemini API 방식은 API key를 사용한다.

const ai = new GoogleGenAI({
  apiKey: process.env.GEMINI_API_KEY,
});

반면 Vertex AI 방식은 Google Cloud project와 location을 사용한다.

const ai = new GoogleGenAI({
  vertexai: true,
  project: 'YOUR_PROJECT_ID',
  location: 'us-central1',
});

여기서 중요한 점은 apiKey가 아니라 Google Cloud IAM 인증을 사용한다는 것이다.

로컬 개발 환경에서는 보통 다음을 실행한다.

gcloud auth login
gcloud auth application-default login

서버에서는 service account를 사용한다.

AWS 서버나 Docker 환경이라면 service account JSON key를 마운트하거나, 더 안전하게는 Workload Identity Federation을 사용할 수 있다.


Vertex AI용 모델명 주의

Gemini Developer API에서 쓰던 모델명과 Vertex AI에서 쓰는 모델명이 다를 수 있다.

예를 들어 아래처럼 preview 모델명을 그대로 쓰면 404가 날 수 있다.

veo-3.1-lite-generate-preview

Vertex AI / Agent Platform 쪽에서는 다음처럼 001 모델명을 사용했다.

veo-3.1-lite-generate-001
veo-3.1-fast-generate-001
veo-3.1-generate-001

실제로 잘못된 모델명을 사용했을 때는 이런 오류가 발생했다.

Publisher model ... was not found or your project does not have access to it.
Ensure you are using a valid model name and that the model is available in the specified region.

이 경우 먼저 확인할 것은 다음이다.

  1. 모델명이 Vertex AI용인지
  2. location이 us-central1인지
  3. 프로젝트에 Vertex AI API가 활성화되어 있는지
  4. 해당 계정 또는 service account에 Vertex AI 권한이 있는지

실제 호출 예시

최종적으로는 이런 형태로 호출했다.

import { GoogleGenAI } from '@google/genai';

const ai = new GoogleGenAI({
  vertexai: true,
  project: process.env.GOOGLE_CLOUD_PROJECT!,
  location: 'us-central1',
});

const operation = await ai.models.generateVideos({
  model: 'veo-3.1-lite-generate-001',
  prompt: 'A cinematic shot of a coffee cup on a wooden table.',
  config: {
    durationSeconds: 4,
    aspectRatio: '16:9',
    resolution: '720p',
    generateAudio: false,
    numberOfVideos: 1,
  },
});

console.dir(operation, { depth: null });

generateAudio: false를 넣는 위치는 config 안이다.

config: {
  generateAudio: false,
}

REST 기준으로 보면 parameters 안에 들어간다.

{
  "instances": [
    {
      "prompt": "A cinematic shot of a coffee cup on a wooden table."
    }
  ],
  "parameters": {
    "durationSeconds": 4,
    "aspectRatio": "16:9",
    "resolution": "720p",
    "generateAudio": false,
    "sampleCount": 1
  }
}

Docker 서버에서 인증하기

내 경우 서버는 AWS에서 Docker로 돌고 있었다.

가장 간단한 방식은 Google service account key를 컨테이너에 마운트하는 것이다.

docker run -d \
  --name app \
  -v /opt/secrets/gcp-veo-sa.json:/secrets/gcp-veo-sa.json:ro \
  -e GOOGLE_APPLICATION_CREDENTIALS=/secrets/gcp-veo-sa.json \
  -e GOOGLE_CLOUD_LOCATION=us-central1 \
  your-image:latest

docker-compose라면 다음처럼 설정할 수 있다.

services:
  app:
    image: your-image:latest
    environment:
      GOOGLE_APPLICATION_CREDENTIALS: /secrets/gcp-veo-sa.json
      GOOGLE_CLOUD_LOCATION: us-central1
    volumes:
      - /opt/secrets/gcp-veo-sa.json:/secrets/gcp-veo-sa.json:ro

주의할 점은 service account JSON key는 사실상 비밀번호라는 것이다.

  • Git에 넣으면 안 된다.
  • Docker image 안에 COPY하면 안 된다.
  • 실행 시 read-only volume으로 마운트하는 편이 낫다.
  • 운영에서는 가능하면 Workload Identity Federation을 쓰는 것이 더 안전하다.

여러 프로젝트를 돌려쓰는 경우

기존에 Gemini API key를 여러 개 쓰고 있었다면, 사실상 여러 프로젝트의 quota를 나눠 쓰고 있었을 가능성이 높다.

Google의 rate limit은 API key 단위가 아니라 project 단위로 적용된다.<citation refs="2lbaLx9jr7WiyEsMZq9oB">Rate limits are applied per project, not per API key.</citation>

Vertex AI에서도 비슷하게 여러 프로젝트를 사용할 수 있다.

다만 API key를 바꿔 끼우는 게 아니라, 하나의 service account에 여러 프로젝트 권한을 주고 projectId만 바꿔 호출하는 구조가 된다.

const projectIds = [
  'project-a',
  'project-b',
  'project-c',
];

let index = 0;

function pickProjectId() {
  const projectId = projectIds[index % projectIds.length];
  index += 1;
  return projectId;
}

function createClient(projectId: string) {
  return new GoogleGenAI({
    vertexai: true,
    project: projectId,
    location: 'us-central1',
  });
}

각 프로젝트에는 동일한 service account를 IAM member로 추가하고, Vertex AI 사용자 역할을 부여하면 된다.

역할 ID는 다음이다.

roles/aiplatform.user

콘솔에서 켜야 하는 것

Google Cloud Console에서는 이름이 조금 헷갈린다.

현재 Google은 Vertex AI를 Gemini Enterprise Agent Platform 쪽으로 개편하고 있다. 공식 블로그에서도 Agent Platform을 Vertex AI의 evolution이라고 설명한다.<citation refs="UYARoatDRpNtFDg_sSx8r">It’s the evolution of Vertex AI... Moving forward, all Vertex AI services and roadmap evolutions will be delivered exclusively through the Agent Platform, rather than as a standalone service</citation>

하지만 실제 API endpoint와 IAM role은 여전히 aiplatform 계열을 사용한다.

콘솔에서는 프로젝트별로 다음을 확인하면 된다.

1. Vertex AI API 활성화

API 및 서비스
→ 라이브러리
→ Vertex AI API
→ 사용 설정

직접 URL:

https://console.cloud.google.com/apis/library/aiplatform.googleapis.com

2. IAM 역할 부여

IAM 및 관리자
→ IAM
→ 액세스 권한 부여

역할:

Vertex AI 사용자

Role ID:

roles/aiplatform.user

3. GCS 저장을 쓴다면 Storage 권한도 추가

Storage Object User

Role ID:

roles/storage.objectUser

정리

이번 문제의 핵심은 generateAudio 파라미터가 SDK 타입에 있다고 해서 모든 API 경로에서 동일하게 동작하는 것은 아니라는 점이었다.

내가 최종적으로 정리한 내용은 다음과 같다.

  1. Gemini Developer API에서는 generateAudio: false가 기대대로 동작하지 않을 수 있다.
  2. Vertex AI / Gemini Enterprise Agent Platform의 VideoGenerationModelParams에는 generateAudio가 명시되어 있다.
  3. Vertex AI 가격표에는 Video + Audio와 Video only가 분리되어 있다.
  4. 따라서 오디오 없는 Veo 영상을 생성해 비용을 줄이려면 Vertex AI API 경로를 쓰는 것이 맞다.
  5. Vertex AI는 API key가 아니라 IAM/service account 인증을 사용한다.
  6. 여러 프로젝트 quota를 쓰고 있다면, service account 하나에 여러 프로젝트 권한을 부여하고 projectId를 로테이션하는 구조로 바꿀 수 있다.

결론적으로, 비용 최적화를 위해서는 단순히 ffmpeg로 오디오를 지우는 것이 아니라, 생성 요청 단계에서 generateAudio: false를 적용할 수 있는 API 경로를 선택해야 한다.

나의 경우 그 답은 Vertex AI API였다.


0개의 댓글