번역 프롬프트 엔지니어링의 한계 — 모델 천장

AI 인프라3분조회 –

영상 자막을 번역해 주는 브라우저 확장을 직접 만들어 씁니다. 시중에도 번역 확장은 많지만 쓸수록 비용이 들고 원하는 대로 손보기가 어려워서 만들게 됐습니다.

번역은 LLM(대규모 언어 모델)에 맡기는데, 구체적으로는 여러 업체의 LLM 을 API 하나로 호출하게 해 주는 AWS 서비스인 AWS Bedrock 을 부릅니다. 번역할 문장을 보내면 번역된 문장이 돌아오는 단순한 구조입니다.

여기서 걸린 게 모델 선택이었습니다. 자막은 영상을 보는 내내 흘러나오고 그때마다 번역을 부르니 호출이 워낙 잦아서 한 줄 한 줄에 크고 좋은 모델을 부르면 느린 데다 오래 볼수록 요금이 쌓입니다.

골라 쓴 건 Bedrock 에 있는 Amazon Nova Lite 같은 작은 모델이고, 크기가 작아 빠르고 싼 대신 번역 품질은 큰 모델보다 떨어집니다. 모델을 더 비싼 걸로 바꾸지 않고 프롬프트(모델에 주는 지시문)만 다듬어서 이 작은 모델의 번역 품질을 어디까지 끌어올릴 수 있는지, 그리고 어디서부터는 프롬프트로 안 되는지를 확인했습니다.

처음 증상 — 전문용어 직역, 관용구 문자 번역

작은 모델은 이런 걸 자주 틀렸고, 유형이 정해져 있었습니다.

  • 전문용어를 뜻으로 풀어버림 — “dirty read” 를 “더러운 읽기”, “primary terms” 를 “기본 용어” 로.
  • 관용구를 문자 그대로 — “under the hood” 를 “후드 아래” 로.
  • 번역투 — 피동 남발, 어색한 어순, 굳이 붙는 대명사.

프롬프트 규칙으로 상당 부분 교정

틀리는 방식이 일정하니 거기에 맞춰 규칙을 하나씩 붙였고, 처음엔 이렇게 시작해서 틀린 게 나올 때마다 한 줄씩 늘려 갔습니다.

영어 자막을 한국어로 번역한다.

- 전문용어는 뜻으로 풀지 말고 음차하거나 원어를 유지한다
- 관용구는 문자 그대로가 아니라 그 맥락의 의미로 옮긴다
- 한국어 어순으로 재구성하고 번역투를 쓰지 않는다
- 굳이 필요 없는 대명사는 뺀다
- 문체는 처음부터 끝까지 일관되게 유지한다

이걸로 더러운 읽기가 더티 리드(dirty read)로 바뀌고 어색한 번역투도 눈에 띄게 줄었습니다.

프롬프트를 손보면서 같이 건드려야 했던 게 캐시입니다. 번역 결과를 캐시해 두고 있어서, 프롬프트를 고쳐도 이전 캐시가 옛날 규칙으로 번역한 결과라 그대로 쓰면 개선이 안 보입니다. 그래서 캐시 키에 프롬프트 버전과 모델 ID 를 같이 넣어, 프롬프트를 고치면 옛 캐시가 자동으로 안 맞게 했습니다.

before  cacheKey = hash(원문)
after   cacheKey = hash(원문 + promptVersion + modelId)

프롬프트나 모델을 바꾸면 키가 달라져서 옛 캐시를 건너뛰니, 고친 결과가 바로 보입니다.

고정 예시가 출력에 그대로 새어 나옴

관용구 규칙을 줄 때는 이런 관용구는 이렇게 번역하라며 고정된 번역 예시를 프롬프트에 박아 뒀습니다.

- 관용구는 그 의미로 옮긴다
  "the tip of the iceberg" → "빙산의 일각일 뿐"
  "under the hood"         → "내부적으로는"

그랬더니 그 예시 문장이 맥락과 상관없이 출력에 튀어나왔습니다. 원문에 빙산 얘기가 없는데도 “빙산의 일각일 뿐” 이 영상 제목 자리에 그대로 찍히는 식이었습니다.

작은 모델은 프롬프트의 구체적 예시를 따라야 할 정답으로 오해하고 복사하는 것이라, 예시를 빼고 원칙만 남겼습니다.

- 관용구는 그 맥락의 의미로 옮긴다
- 제목은 제목답게 짧게 옮긴다

무엇을 하라는 말만 남기고 결과물을 안 보여주자 복사가 멈췄습니다.

못 고친 것 — 모델의 천장

프롬프트로 잡을 수 있는 건 체계적인 오류뿐이라, 늘 같은 방식으로 틀리는 것(전문용어 직역, 번역투)만 규칙으로 교정됩니다.

그런데 “문장을 얼마나 매끄럽게 만드느냐” 같은 기본 생성력은 프롬프트로 안 올라갑니다. 그건 모델의 천장이라 모델을 바꿔야 올라갑니다. 팝업에서 모델 ID 를 바꿀 수 있게 하고(더 큰 모델로 교체 가능), 캐시 키에 모델 ID 를 넣어 A/B 결과가 안 섞이게 했습니다.

프롬프트로 되는 것과 모델을 바꿔야 하는 것

작은 모델을 프롬프트로 다듬는 건 가성비가 좋지만 어디까지 되는지가 꽤 분명하게 갈렸습니다. 늘 같은 방식으로 틀리는 체계적 오류는 규칙으로 잡힙니다. 다만 그 규칙은 구체 예시가 아니라 일반 원칙으로 줘야 하는데, 예시를 고정으로 박아 두면 작은 모델이 그걸 정답 문장으로 알고 복사하기 때문입니다. 문장이 얼마나 매끄러운가 같은 기본 생성력은 아무리 써도 안 올라가니, 그 위를 원하면 모델을 바꿔야 합니다.

번역 품질이 아쉬울 때는 틀리는 방식이 일정한지부터 보면 되고, 일정하면 프롬프트에 원칙을 하나 더할 자리고, 매번 다른 식으로 어색하면 그건 모델의 천장이라 모델 ID 를 바꿔 보는 게 빠릅니다.

  1. 불러오는 중