Vertex AI 이미지 파이프라인의 오류를 디버깅하고 마침내 안정화시킨 과정
요약
Vertex AI를 이용한 이미지 생성 파이프라인 구축 중 발생한 인증 및 권한 오류를 해결하는 과정을 다룹니다. 모델 자체의 문제보다 자격 증명, 프로젝트 설정, 할당량 관리 등 인프라 측면의 디버깅이 중요함을 강조합니다.
핵심 포인트
- 실패의 주원인은 모델이 아닌 자격 증명, 프로젝트, 정책 설정에 있음
- 신뢰할 수 있는 단일 소스(Source of Truth) 스크립트를 확보하여 하드코딩된 프로젝트 ID 확인
- 무료 티어와 유료 경로(Vertex AI)의 실패 모드가 다르므로 반드시 분리하여 관리
- 코드 수정 전 서비스 계정의 토큰 발행 가능 여부를 먼저 검증할 것
지난주, 나는 실제 창의적인 작업보다 AI 인프라에 더 많은 시간을 허비했다.
작업은 단순해 보였다: 콘텐츠 파이프라인을 위해 Vertex AI를 통해 이미지를 생성하는 것.
실제로 일어난 일은 다음과 같다:
- 어제는 작동하던 키가 오늘은 실패함
- 한 프로젝트는
invalid_grant를 반환함 - 다른 프로젝트는
permission denied를 반환함 - 무료 티어 (free tier)는 가끔 작동하다가 할당량 제한 (quota walls)에 걸림
- 코드는 멀쩡해 보였지만, 시스템은 여전히 이미지를 생성하지 못함
이것이 아무도 말해주지 않는 AI 워크플로우의 이면이다:
대부분의 실패는 모델의 실패가 아니다. 그것은 자격 증명 (credential), 프로젝트, 그리고 정책 (policy)의 실패다.
내가 어떻게 이 모든 것을 마침내 디버깅하고 이미지 경로를 다시 작동하게 만들었는지 그 방법을 공유한다.
증상 (The symptoms)
처음에는 실패 원인들이 서로 관련이 없어 보였다.
나는 세 가지 다른 유형의 오류를 목격했다:
invalid_grant: account not found
403 Permission denied
429 RESOURCE_EXHAUSTED
그것은 보통 다음 두 가지 중 하나를 의미한다:
- 시스템의 여러 곳이 고장 났다
- 시스템이 여러 환경을 가리키고 있으며, 당신은 어떤 것이 실제 환경인지 모른다
내 경우에는 두 번째 경우였다.
1단계: 어떤 경로가 정식(canonical)인지 추측하는 것을 멈춰라
첫 번째로 유용했던 조치는 잔인할 정도로 단순했다:
팀이 실제로 신뢰하는 단 하나의 스크립트를 찾는 것.
우리에게 그것은 다음과 같았다:
~/clawd/ops/production/scripts/generate_panels.py
그것이 신뢰할 수 있는 단일 출처 (source of truth)가 되었다.
오래된 코드 조각 (snippets)이 아니다.
절반만 작동하는 노트북 (notebooks)도 아니다.
기억력에 의존하는 것도 아니다.
실제 스크립트를 확인하자마자, 나는 숨겨진 문제 하나를 즉시 발견했다:
PROJECT = "old-project-id"
파이프라인이 여전히 오래된 프로젝트로 하드코딩되어 있었다.
그래서 내가 자격 증명 (credentials)을 업데이트했을 때조차, 요청은 여전히 잘못된 곳으로 전송되고 있었다.
그 사실 하나만으로도 많은 것이 설명되었다.
2단계: 무료 티어 실패와 유료 경로 실패를 분리하라
우리는 두 가지 서로 다른 경로를 섞어서 사용하고 있었다:
- Gemini API / AI Studio 무료 티어 (free tier)
- Vertex AI 유료 경로 (paid route)
이것은 무해하게 들릴 수 있지만, 끔찍한 디버깅 환경을 만든다.
왜냐하면 실패 모드 (failure modes)가 서로 다르기 때문이다:
- free tier(무료 계층)는 할당량(quota) 오류로 중단됨
- Vertex는 IAM / 서비스 계정(service account) / 프로젝트 오류로 중단됨
이 둘을 섞어버리면 잘못된 문제를 해결하기 시작하게 된다.
예를 들어, 처음에는 이것이 모델 문제처럼 보였다:
429 RESOURCE_EXHAUSTED
하지만 알고 보니 단순히 무료 계층(free-tier) 키가 소진된 것이었다.
그동안 유료 경로는 완전히 다른 이유로 실패하고 있었다.
교훈: 동일한 모델을 사용하더라도 무료와 유료를 별개의 시스템으로 취급하라.
단계 3: 코드를 건드리기 전에 서비스 계정(service account)을 검증하라
새로운 Vertex JSON을 확보한 후, 나는 바로 이미지를 생성하기 시작하지 않았다.
대신 해당 자격 증명(credential)이 토큰을 발행할 수 있는지부터 확인하기 시작했다.
이러한 종류의 테스트는 문제가 무엇인지 알려주기 때문에 시간을 절약해 준다:
- 인증 (auth)
- 프로젝트 권한 (project permissions)
- 또는 모델 호출 (model invocation)
Python에서의 로직은 기본적으로 다음과 같다:
from google.oauth2 import service_account
from google.auth.transport.requests import Request
...
만약 이 단계에서 실패한다면, 프롬프트(prompt)를 건드리지 마라.
모델을 건드리지 마라.
렌더링(rendering) 코드를 건드리지 마라.
당신에게는 아직 이미지 문제가 있는 것이 아니다.
인증(auth) 문제가 있는 것이다.
단계 4: 조직 정책(organization policies)을 주의하라
이 부분이 가장 많은 시간을 잡아먹었다.
새로운 서비스 계정(service account)을 생성했고 모든 것이 올바르게 보였지만, Google Cloud가 JSON 키 생성을 거부했다.
오류의 원인은 다음 정책 때문인 것으로 밝혀졌다:
iam.disableServiceAccountKeyCreation
첫 화면에서는 이것이 명확하지 않았다.
UI는 한 정책을 "강제되지 않음(not enforced)"으로 표시했지만, 그 상위 어딘가에 레거시 제약 조건(legacy constraint)이 여전히 활성화되어 있었다.
이러한 불일치 때문에 클라우드 디버깅이 저주받은 것처럼 느껴지는 것이다.
실질적인 해결책은 동일한 프로젝트와 계속 싸우는 것이 아니었다.
실질적인 해결책은 상속된 조직 정책(org-policy)의 짐이 없는 깨끗한 개인 프로젝트를 만드는 것이었다.
그것이 관리자 정책 상태를 풀려고 시도하는 것보다 결국 더 빨랐다.
단계 5: 깨끗한 프로젝트 하나를 만들고 진행하라
최종적으로 작동하는 설정은 다음과 같았다:
- 새로운 깨끗한 Vertex 프로젝트
- 새로운 서비스 계정 (Service Account)
- 새로운 JSON 키
- 새로운 프로젝트 ID로 업데이트된 표준 스크립트 (Canonical Script)
- 전체 경로가 작동함을 증명하는 단 한 번의 성공적인 테스트 생성
그제서야 나는 경로가 수정되었다고 판단했다.
키가 존재할 때가 아니었다.
정책 화면이 초록색으로 보일 때도 아니었다.
스크립트가 더 이상 충돌하지 않을 때도 아니었다.
오직 다음과 같이 실제 파일이 생성되었을 때뿐이었다:
outputs/nanobanana_vertex_test.png
그것만이 유일하게 의미 있는 결과였다.
작동하는 멘탈 모델 (Mental Model)
AI 이미지 파이프라인이 깨지면, 나는 이제 다음 순서로 확인한다:
- 어떤 스크립트가 표준(Canonical)인가?
- 요청이 실제로 어떤 프로젝트에 도달하고 있는가?
- 자격 증명(Credential)이 토큰을 발행할 수 있는가?
- 이것이 무료 티어 할당량(Quota)인가, 아니면 Vertex IAM인가?
- 조직 정책(Org Policy)이 서비스 계정 키를 차단하고 있는가?
- **실제 이미지 하나를 성공적으로 생성했는가?
이 순서를 따르는 것이 무작위로 키를 바꾸고 프롬프트를 다시 실행하는 것보다 훨씬 빠르다.
실제로 문제를 해결한 것
우리에게 최종적인 해결책은 "더 나은 프롬프팅"이 아니었다.
그것은 다음과 같았다:
- 오래된 프로젝트 ID에 대한 의존 중단
- 손상된 자격 증명 교체
- 무료 티어와 유료 경로의 분리
- 상속된 조직 정책(Org-policy) 함정 피하기
- 실제 출력 파일로 파이프라인을 엔드 투 엔드(End-to-end)로 테스트하기
화려하지는 않다.
하지만 이것이 신뢰할 수 있는 파이프라인과, 운이 좋을 때만 작동하는 파이프라인의 차이를 만든다.
마지막 생각
많은 AI 도구 관련 담론은 여전히 모델에 집착하고 있다.
하지만 일단 이러한 시스템을 프로덕션(Production) 환경에서 다루게 되면, 진짜 병목 현상은 훨씬 더 지루한 경우가 많다:
ID(Identity), 권한(Permissions), 할당량(Quotas), 그리고 프로젝트 위생(Project Hygiene).
모델이 최첨단(State of the art)일지라도,
프로젝트 그래프가 엉망이라면 당신은 여전히 제품을 출시할 수 없다.
Terminal Skills가 지향하는 바
이것이 바로 내가 Terminal Skill로 만들고 싶은 워크플로우의 전형이다.
기술이 마법처럼 클라우드 설정을 숨겨야 하기 때문이 아니라, 디버깅 순서가 누군가의 기억 속에만 머물러 있어서는 안 되기 때문이다.
유용한 vertex-ai-image-pipeline 스킬이 있다면 에이전트에게 다음과 같은 반복 가능한 체크리스트를 제공할 수 있을 것입니다:
- 표준 스크립트 (canonical script) 식별
- 설정된 프로젝트 ID (project id) 확인
- 서비스 계정 (service account)이 토큰을 발행 (mint)할 수 있는지 테스트
- 프리 티어 (free-tier) 할당량 (quota) 실패와 Vertex IAM 실패를 구분
- 조직 정책 (organization-policy) 차단 요소 확인
- 프롬프트 (prompt)를 수정하기 전에 최소한의 생성 테스트 실행
- 추측하는 대신 정확히 실패한 레이어 (layer)를 보고
이것이 Terminal Skills의 더 넓은 개념입니다. 즉, 엉망이고 실제적인 운영 워크플로 (operational workflows)를 재사용 가능한 에이전트 스킬로 전환하는 것입니다.
저는 아마도 다음 단계로 이 글을 적절한 Terminal Skills 활용 사례로 번역하게 될 것입니다. 왜냐하면 이것이 바로 에이전트에게 또 다른 프롬프트 템플릿 (prompt template)보다 더 필요한, 지루하지만 실제적인 운영 워크플로 (production workflow)의 종류이기 때문입니다.
최근에 고장 난 AI 파이프라인 (pipeline)을 디버깅해야 했던 적이 있다면, 당신에게 무엇이 가장 먼저 실패했는지 진심으로 듣고 싶습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기