BookTranslator
BookTranslator

로컬 LLM으로 긴 문서를 번역하는 방법: 청크와 검증

LM Studio에서 로컬 LLM으로 3,179단어를 세 가지 방식으로 번역했고, 각 방식에는 조용한 오류가 숨어 있었습니다. 그 오류를 잡아내는 청크 크기, 설정, 검증 방법을 정리합니다.

BookTranslator

BookTranslator Team

25 min read

사람들이 로컬 LLM으로 문서를 번역하는 이유는 하나입니다. 파일이 자신의 컴퓨터를 떠날 수 없기 때문입니다. 로컬 모델도 작업을 수행할 수 있지만, 번역된 파일이 아니라 일반 텍스트를 돌려주며, 가장 심각한 실수는 조용히 일어납니다. 우리 테스트에서 3,179단어 발췌문에 대한 단일 요청은 올바른 문단 수와 깔끔한 종료 신호를 반환했지만, 한 문단은 내용의 3분의 1 이상이 사라지고 원문에 없는 문장이 추가되어 있었습니다.

간단한 답: 텍스트를 문단 경계에서 약 600단어 단위의 청크로 나누고, 이름과 반복되는 용어의 용어집을 시스템 지시에 넣고, 모델의 사고 모드를 끄고, 신뢰하기 전에 각 청크를 원문 문단과 문단별로 비교하세요. 우리가 테스트한 세 가지 방식 모두 어딘가에서 실패했고, 어떤 실패도 오류 메시지를 내지 않았습니다. 노트북의 중간 크기 모델이 책 한 권을 처리하는 데 몇 시간이 걸릴 것으로 예상하고, 서식은 직접 다시 만들어야 한다고 계획하세요.

아래 내용은 모두 2026년 10월 23일의 한 번의 실행에서 나왔습니다: Apple M4 Max(메모리 64GB)의 LM Studio 0.4.8에서 Qwen 3.6 27B(Q4_K_M GGUF)로 카프카의 Die Verwandlung 서두를 독일어에서 영어로 번역했습니다. 테스트 스크립트, 결과, 원시 실패 예시를 무료로 내려받아 자신의 모델로 반복해 볼 수 있습니다.

로컬 LLM이 적합한 도구일 때

편의성 때문이 아니라 문서의 규칙 때문에 결정되는 경우에만 번역을 로컬에서 실행하세요:

  • 고객 계약서, 연구 협약서, 또는 고용주 정책이 파일을 외부 서비스에 업로드하는 것을 금지하는 경우;
  • 텍스트가 개인적이거나 기밀이라 민감한 부분을 먼저 제거할 수 없는 경우; 또는
  • 문서당 비용 없이 많은 파일을 처리해야 하고 이미 적합한 하드웨어를 보유한 경우.

이 중 어느 것도 해당하지 않는다면, 로컬 모델은 보통 더 느린 경로로 더 나쁜 결과를 낳습니다. 문서 번역 서비스가 제공하는 세 가지를 포기하게 됩니다: 원본 형식의 번역된 파일, 자신의 기기가 감당할 수 있는 것보다 큰 모델, 그리고 책 전체에 걸쳐 일관성을 위해 설계된 워크플로입니다. 어느 경로를 선택하든 문서 번역 개인정보 보호 체크리스트를 먼저 검토하세요. 파일 처리 권한, 최소 작업 사본, 서비스가 업로드를 어떻게 처리하는지 다룹니다.

"로컬"이라는 말에도 정확한 의미가 필요합니다. 모델은 당신의 컴퓨터에서 실행되며, 우리 테스트에서 요청은 localhost로만 전송되었습니다. 하지만 그것만으로는 모델을 둘러싼 앱이 무엇을 기록하고, 업데이트하고, 보고하는지 알 수 없습니다. 기기 밖으로 아무것도 나가지 않는다는 증거가 규칙상 필요하다면, 런타임 자체의 설정과 정책을 확인하거나 네트워크 접근이 없는 기기에서 실행하세요.

테스트한 내용

우리는 Die Verwandlung의 첫 19개 문단(독일어 3,179단어)을 퍼블릭 도메인 Project Gutenberg 판본에서 번역했습니다. 문학적 독일어는 공정한 스트레스 테스트입니다: 문단이 길고, 문장이 중첩되며, 같은 인물과 직함이 반복됩니다.

세 실행 모두 동일한 모델과 설정을 사용했습니다: temperature 0.2, 최대 출력 토큰 12,000개, 16,384토큰 컨텍스트 창. 지시는 독일어 문단당 영어 문단 하나를 요구했고 그 외에는 아무것도 요구하지 않았습니다.

실행보낸 내용출력 문단 수(원문: 19)출력 단어 수시간
A. 청크 분할약 600단어씩 6개 청크, 지시만 포함193,31910.4분
B. 청크 분할 + 용어집 + 문맥동일한 청크, 7개 용어집, 그리고 "번역하지 마시오"라고 표시된 이전 원문 단락203,44610.5분
C. 단일 요청19개 단락을 한 번에193,3099.5분

모든 실행은 정상 종료 신호와 함께 끝났고, 모든 실행에는 서로 다른 조용한 오류가 포함되어 있었다. 실행 C는 텍스트를 누락시키고 만들어냈다. 실행 B는 건너뛰라고 지시받은 텍스트를 번역했다. 가장 깔끔했던 실행 A는 마지막 청크에서 한 인물에게 잘못된 역할을 부여했다.

실패 1: 하나의 큰 요청이 단락의 일부를 누락시켰다

실행 C는 정상적으로 완료되었고 정확히 19개의 단락을 반환했다. 단락 수 검사만으로는 통과했을 것이다. 그러나 6번 단락은 260단어 원문에 대해 214단어로 돌아왔다.

원문에서 그레고르는 시계를 보고 기차를 놓쳤음을 깨닫고, 이어서 병가를 내는 것을 고려한다. 상사가 건강보험 의사와 함께 올 텐데, 그 의사는 모든 사람을 건강하지만 일하기 싫어하는 사람으로 여기며, 그레고르는 졸음과 이상한 식욕 외에는 실제로 몸이 괜찮다고 인정한다. 실행 C는 첫 부분을 번역한 뒤, 단락의 260개 독일어 단어 중 98개에 해당하는 병가 관련 구절 전체를 누락시켰다. 그 대신 그레고르가 "즉시 해고되었을 것"이라거나, 사무 보조원이 "보고된 모든 것을 자신을 과시할 기회로 보는" 경향이 있다거나, 그 생각이 "그의 입가에 미소를 띠게 했다"고 썼다. 그중 어느 것도 독일어 원문에는 없다.

청크 단위 실행은 같은 단락을 267단어로 완전히 번역했다.

하나의 표본만으로 긴 요청이 항상 실패한다고 증명할 수는 없다. 다만 무엇을 확인해야 하는지는 보여준다. 긴 단일 요청은 구조적으로 완전해 보이면서도 조용히 텍스트를 압축하거나 만들어낼 수 있다. 독일어를 모르는 독자라면 알아챌 이유가 없을 것이다.

실패 2: 모델이 건너뛰라고 지시받은 "맥락"을 번역했다

흔한 팁은 모델이 흐름을 유지하도록 각 청크와 함께 이전 단락을 보내는 것이다. 실행 B에서는 이를 "맥락 (이미 번역됨, 번역하지 마시오)"이라는 레이블 아래 메시지에 추가했다.

청크 4에서 모델은 그럼에도 불구하고 이를 번역했다. 해당 청크는 원문 3개 단락에 대해 4개 단락을 반환했고, 첫 번째는 청크 3의 마지막 단락을 다시 번역한 것이었다. 합쳐지면 책에는 그 단락이 매번 다른 표현으로 두 번 포함되었을 것이다.

실용적인 규칙: 맥락을 보낸다면 모델이 번역하도록 요청받는 텍스트에서 분리하고, 짧게 유지하며, 모든 청크의 단락 수를 확인하라. 확인할 수 없다면 빼라.

실패 3: 단독으로 보낸 청크가 인물에게 잘못된 역할을 부여했다

실행 A는 용어집도 맥락도 없이 각 청크를 보냈다. 처음 다섯 청크에서는 이 방식이 잘 작동했다. Prokurist는 등장한 16곳 모두에서 "수석 서기"로 번역되었다. 여섯 번째 청크는 수석 서기가 문 너머로 그레고르를 꾸짖는 단일 단락이었다. 단독으로 보았을 때 모델은 der Prokurist를 그레고르 자신의 직업인 "외판원"으로 번역했다. 단락 수는 일치했고 길이 비율은 1.00이었으므로 어느 구조적 검사도 알아채지 못했다.

시스템 지시에 용어집이 있고 이전 단락이 맥락으로 제공된 실행 B에서는 같은 단락이 "수석 서기"를 올바르게 사용했다. 이 테스트만으로는 둘 중 무엇이 문제를 해결했는지 알 수 없다. 맥락이 실패 2도 일으켰으므로, 이름과 역할을 청크 간에 전달하는 더 안전한 장소는 용어집이다. 용어집은 짧고 지시 안에 있으며 기계적으로 확인할 수 있다.

견뎌낸 워크플로

1. 먼저 파일에서 일반 텍스트를 추출하라

로컬 LLM은 파일이 아니라 텍스트를 번역한다. 시작하기 전에 문서를 변환하라:

  • DOCX 또는 EPUB: 블록당 하나의 단락으로 일반 텍스트나 Markdown으로 내보내고, 제목은 별도 줄로 유지하라.
  • 텍스트 레이어가 있는 PDF: 텍스트를 추출한 뒤 끊어진 줄과 하이픈 연결을 복구하라. OCR 줄바꿈 및 하이픈 연결 수정 가이드에서 동일한 정리 작업을 다룬다. Docling과 같은 변환기는 PDF와 Office 파일에서 Markdown을 생성할 수 있다.
  • 스캔한 PDF: 먼저 OCR을 실행하라. PDF에 사용 가능한 텍스트가 있는지 확실하지 않다면 PDF 텍스트 추출 vs OCR을 참고하라.

문단 구조를 그대로 유지하세요. 이후의 모든 검사는 원문과 번역문 문단이 일대일로 대응하는지에 달려 있습니다.

2. 사고 모드를 끄고 확인하세요

현재의 많은 오픈 모델은 답변 전에 추론을 합니다. 번역에서는 이것이 시간과 출력 토큰을 낭비합니다. 저희 설정에서 200토큰짜리 테스트 요청은 199토큰을 추론에 쓰고 빈 답변을 반환했습니다.

일반적인 세 가지 스위치를 시도했습니다. 프롬프트에 /no_think 를 추가해도 아무 효과가 없었고, enable_thinking: false 를 사용한 chat_template_kwargs 도 아무 효과가 없었습니다. 요청에 "reasoning_effort": "none" 을 보내자 추론이 꺼졌습니다. 응답은 추론 토큰 0개를 보고하고 번역을 바로 반환했습니다. 이 매개변수는 LM Studio의 채팅 완료 페이지에 나와 있지 않으므로, 이 모델과 버전 0.4.8에서 관찰한 동작으로 취급하세요. 어떤 스위치도 믿지 말고 직접 응답의 reasoning_tokens 개수를 확인하세요.

3. 청크보다 먼저 컨텍스트 창 크기를 정하세요

컨텍스트 창은 지시문, 청크, 전체 번역을 담을 수 있어야 합니다. 저희의 청크 실행에서 500–670단어 독일어 청크는 용어집과 문맥에 따라 약 800–1,500 입력 토큰과 640–870 출력 토큰을 사용했으므로, 수천 토큰이면 충분합니다. 3,179단어짜리 단일 요청은 4,953 입력 토큰과 3,930 출력 토큰이 필요했습니다.

Ollama는 사용 가능한 메모리에 따라 기본 컨텍스트 길이를 설정합니다. 2026년 10월 23일에 확인한 컨텍스트 길이 문서에 따르면 VRAM 24GiB 미만에서는 4k 토큰, 24–48GiB에서는 32k, 48GiB 이상에서는 256k입니다. OLLAMA_CONTEXT_LENGTH 로 늘릴 수 있습니다. LM Studio에서는 모델을 로드할 때 컨텍스트 길이를 설정하세요. 청크와 그 번역이 맞지 않으면 출력이 잘릴 수 있습니다.

4. 문단 경계에서 약 600단어로 청크하세요

문단이나 문장 안에서 절대 나누지 마세요. 저희 청크는 700단어를 목표로 하고 가장 가까운 문단 경계에서 끝났으며, 그 결과 243–667단어의 청크 6개가 만들어졌습니다. 작은 청크는 비용이 적습니다. 실행 A는 단일 요청의 9.5분에 비해 10.4분이 걸렸고, 실패한 청크는 다시 실행하기 저렴합니다.

지시문은 짧게 유지하고 모든 청크에 동일하게 적용하세요. 저희 지시문은 다음과 같았습니다. 영어로 번역하고, 입력 문단마다 정확히 하나의 출력 문단을 빈 줄로 구분해 유지하며, 번역만 출력하세요. 같은 지시문에 용어집을 추가하세요. 이름, 직함, 반복되는 용어마다 한 줄씩 Prokurist = chief clerk 형식으로 작성합니다. 무엇을 포함할지는 번역 용어집 만들기 가이드에서 다룹니다. 짧은 청크는 주변 이야기를 잃게 되며, 용어집이 그 이야기를 전달합니다.

5. 청크를 합치기 전에 각각을 검사하세요

각 청크에 대해 세 가지 검사를 실행하세요:

  1. 문단 수. 출력은 입력과 같은 수의 문단을 가져야 합니다. 이것이 실패 2를 잡아냈습니다.
  2. 문단별 길이 비율. 각 번역 문단의 단어 수를 원문과 비교하세요. 이것이 문단 수 검사가 놓친 실패 1을 잡아냈습니다.
  3. 문단별 용어집 용어. 원문 용어가 나타나는 곳에서 필요한 번역이 같은 횟수로 나타나야 합니다. 이것이 다른 두 검사가 모두 놓친 실패 3을 잡아냈습니다. 굴절어는 독일어나 러시아어 용어의 형태가 바뀌므로 여기서는 어느 정도 판단이 필요합니다.

독일어에서 영어로의 산문에서 실행 A의 문단은 입력 단어당 출력 단어가 0.98에서 1.17 사이를 유지했습니다. 실행 C의 손상된 문단은 0.82였습니다. 해당 언어 쌍에서 신뢰할 수 있는 몇 개의 문단을 확인하여 자신만의 범위를 설정하세요. 저희 스크립트의 기본값은 표준이 아니라 시작점입니다.

표시된 문단은 먼저 읽어볼 곳이지 오류의 증거가 아닙니다. 그런 다음 번역 자체를 읽으세요. 특히 이름, 숫자, 부정 표현, 그리고 독자가 행동할 만한 내용을 주의 깊게 보세요. 책 번역 QA 체크리스트에서 그 검토를 다룹니다.

6. 문서를 재구성하세요

모델은 텍스트를 반환합니다. 제목, 각주, 표, 이미지, 페이지 레이아웃, 스타일은 수작업이나 변환 도구로 다시 넣어야 합니다. 짧은 보고서에서는 이 작업이 사소합니다. 각주와 표가 있는 책이라면 번역보다 오래 걸릴 수 있습니다.

책 한 권 전체는 얼마나 걸릴까

저희 청크 실행은 3,179단어를 10.4분에 번역했으며, 이 컴퓨터에서 분당 약 300단어입니다. 그 속도라면 90,000단어 소설은 검사와 재실행 전에 대략 5시간의 생성이 걸릴 것입니다. 이는 한 번의 실행에서 나온 단순한 산술이지 벤치마크가 아닙니다. 속도는 모델 크기, 양자화, 하드웨어, 언어 쌍, 그리고 컴퓨터가 다른 작업을 얼마나 하는지에 따라 달라집니다.

모델 파일은 디스크에서 17.5GB였고, 컨텍스트 캐시와 런타임 버퍼에 그 위로 메모리가 필요하므로, 컴퓨터는 파일 크기보다 눈에 띄게 더 많은 여유 메모리가 필요합니다. 더 작은 모델은 보통 품질에서 어느 정도 손해를 보면서 더 빠르고 더 적은 메모리로 실행됩니다. 책 전체를 맡기기 전에 대표 샘플로 테스트하세요. 번역에 가장 좋은 LLM 가이드에서 그 샘플을 만들고 모델을 공정하게 비교하는 방법을 설명합니다.

로컬 LLM 또는 문서 번역 서비스

질문로컬 LLM문서 번역 서비스
파일이 내 컴퓨터를 떠날 수 있는가?필요 없음필요함
결과물직접 재조립해야 하는 일반 텍스트번역된 파일
모델 크기내 메모리에 의해 제한됨제공업체에 의해 제한됨
책 전체에 걸친 일관성내가 할 일: 용어집, 청킹, 검사일부 서비스에 내장됨
문서당 비용내 하드웨어와 시간문서당 또는 단어당 가격

규칙상 파일 업로드가 허용된다면, 문서 서비스가 위 작업의 대부분을 없애줍니다. BookTranslator 는 완전한 PDF, EPUB, DOCX 파일을 번역하여 번역된 파일을 반환하며, FAQ에 따르면 업로드된 파일과 번역 결과물은 AI 모델 학습에 사용되지 않습니다. 클라우드 서비스이므로 파일이 반드시 내 컴퓨터에 있어야 하는 경우에는 선택지가 아닙니다. 모델을 직접 실행하는 것과 서비스 비용을 지불하는 것 사이에서 고민 중이라면, LLM 번역의 실제 비용에서 토큰 측면의 예산을 어떻게 책정할지 확인할 수 있습니다.

테스트 파일 받기

모든 파일은 /files/blog/translate-with-local-llm/ 폴더에 있습니다:

  • local_llm_translation_test.py: LM Studio의 로컬 API를 대상으로 한 전체 테스트로, 세 번의 실행이 모두 포함되어 있습니다. 다른 모델이나 원본 텍스트를 지정하여 테스트를 반복할 수 있습니다.
  • check_translation.py: 원본 텍스트와 번역을 문단별로 비교하여 문단 수 불일치, 범위를 벗어난 길이 비율, 누락된 용어집 용어를 출력합니다(--term "Prokurist=chief clerk" 사용). 어떤 도구의 출력과도 함께 사용할 수 있습니다.
  • results.csv: 문단 수, 단어 수, 토큰 수, 시간이 포함된 모든 요청 기록.
  • failure-examples.txt: 세 가지 실패 사례 모두에 대한 독일어 원본과 모델의 원시 출력.

긴 번역문에 의존하기 전에, 용어집 용어를 넣어 check_translation.py 를 실행해 보세요. 몇 초면 끝나며, 이번 테스트에서 세 가지 실패를 모두 잡아냈습니다. 유창한 문장이 틀렸는지까지는 알려주지 못하므로, 표시된 문단은 읽기를 시작할 지점일 뿐 끝낼 지점은 아닙니다.

관련 글