BookTranslator
BookTranslator

Как переводить длинные документы с помощью локальной LLM: чанки и проверки

Мы перевели 3179 слов с помощью локальной LLM в LM Studio тремя способами, и каждый скрывал незаметную ошибку. Размер чанка, настройки и проверки, которые их выявляют.

BookTranslator

BookTranslator Team

12 min read

Люди переводят документы с помощью локальной LLM по одной причине: файл не может покинуть их компьютер. Локальная модель справляется с задачей, но выдаёт простой текст, а не переведённый файл, и её худшие ошибки тихие. В нашем тесте один запрос на отрывок из 3179 слов вернулся с правильным числом абзацев и чистым сигналом завершения, однако один абзац потерял более трети содержания и приобрёл предложения, которых нет в исходнике.

Короткий ответ: разбейте текст по границам абзацев на чанки примерно по 600 слов, поместите глоссарий имён и повторяющихся терминов в системную инструкцию, отключите режим размышления модели и сравнивайте каждый чанк с исходным абзацем абзац за абзацем, прежде чем доверять ему. Каждый из трёх способов, которыми мы запускали тест, где-то дал сбой, и ни один сбой не выдал сообщения об ошибке. Ожидайте, что модель среднего размера на ноутбуке потратит часы на целую книгу, и планируйте восстанавливать форматирование самостоятельно.

Всё ниже взято из одного запуска 23 октября 2026 года: Qwen 3.6 27B (Q4_K_M GGUF) в LM Studio 0.4.8 на Apple M4 Max с 64 ГБ памяти, перевод начала Die Verwandlung Кафки с немецкого на английский. Тестовый скрипт, результаты и примеры исходных сбоев можно бесплатно скачать, чтобы повторить с вашей собственной моделью.

Когда локальная LLM — подходящий инструмент

Запускайте перевод локально, когда решение диктуют правила работы с документом, а не удобство:

  • клиентский договор, исследовательское соглашение или политика работодателя запрещают загружать файл во внешний сервис;
  • текст является личным или конфиденциальным, и вы не можете сначала удалить чувствительные части; или
  • вам нужно обработать много файлов без затрат на каждый документ, и у вас уже есть подходящее оборудование.

Если ничего из этого не применимо, локальная модель обычно оказывается более медленным путём к худшему результату. Вы отказываетесь от трёх вещей, которые предоставляет сервис перевода документов: переведённого файла в исходном формате, модели крупнее, чем может вместить ваша машина, и рабочего процесса, построенного для согласованности по всей книге. Прежде чем выбирать любой из путей, проработайте контрольный список конфиденциальности при переводе документов. Он охватывает полномочия на обработку файла, минимальные рабочие копии и то, что сервис делает с загрузками.

«Локальный» также требует точного определения. Модель работает на вашем компьютере, и в нашем тесте запросы шли только на localhost. Это не говорит о том, что приложение вокруг модели логирует, обновляет или передаёт. Если ваши правила требуют доказательства, что ничего не покидает устройство, проверьте собственные настройки и политику среды выполнения или запускайте её на машине без доступа к сети.

Что мы тестировали

Мы перевели первые 19 абзацев Die Verwandlung (3179 немецких слов) из общедоступного издания Project Gutenberg. Литературный немецкий — справедливый стресс-тест: абзацы длинные, предложения вложенные, одни и те же персонажи и должности повторяются.

Все три запуска использовали одну и ту же модель и настройки: температура 0.2, максимум 12 000 выходных токенов и контекстное окно 16 384 токена. Инструкция требовала один английский абзац на каждый немецкий абзац и ничего больше.

ЗапускЧто мы отправилиАбзацев на выходе (в источнике: 19)Слов на выходеВремя
A. По чанкам6 чанков примерно по 600 слов, только инструкция193,31910,4 мин
B. По чанкам + глоссарий + контекстТе же фрагменты, глоссарий из 7 терминов и предыдущий исходный абзац с пометкой «НЕ переводить»203,44610,5 мин
C. Один запросВсе 19 абзацев сразу193,3099,5 мин

Каждый запуск завершился нормальным сигналом остановки, и в каждом была своя тихая ошибка. В запуске C текст был потерян и выдуман. В запуске B модель перевела текст, который ей велели пропустить. В запуске A, самом чистом, один персонаж получил неверную роль в последнем фрагменте.

Ошибка 1: один большой запрос потерял часть абзаца

Запуск C завершился нормально и вернул ровно 19 абзацев. Проверка количества абзацев его бы пропустила. Однако абзац 6 вернулся с 214 словами вместо 260 в исходнике.

В исходнике Грегор смотрит на часы, понимает, что опоздал на поезд, и затем думает о том, чтобы сказаться больным: его начальник явился бы с врачом страховой кассы, который считает всех здоровыми, но не желающими работать, и Грегор признаёт, что на самом деле чувствует себя хорошо, если не считать сонливости и необычного аппетита. Запуск C перевёл первую часть, а затем отбросил весь отрывок про больничный — 98 из 260 немецких слов абзаца. Вместо него он написал, что Грегора «тут же уволили бы», что конторский служащий склонен «видеть во всём, что ему докладывают, повод показать себя», и что эта мысль «вызвала у него улыбку». Ничего этого в немецком тексте нет.

Запуск с фрагментами перевёл тот же абзац полностью, в 267 словах.

Один пример не доказывает, что длинные запросы всегда дают сбой. Он показывает, что нужно проверять: длинный одиночный запрос может незаметно сжать или выдумать текст, при этом выглядя структурно полным. У читателя, не знающего немецкого, не было бы причин это заметить.

Ошибка 2: модель перевела «контекст», который ей велели пропустить

Распространённый совет — отправлять предыдущий абзац вместе с каждым фрагментом, чтобы модель сохраняла нить. В запуске B мы добавили его в сообщение с пометкой «Контекст (уже переведён, НЕ переводить)».

Во фрагменте 4 модель всё равно его перевела. Фрагмент вернул четыре абзаца вместо трёх исходных, и первый был вторым переводом последнего абзаца фрагмента 3. Если соединить, книга содержала бы этот абзац дважды, с разными формулировками.

Практическое правило: если вы отправляете контекст, держите его вне текста, который модели велено переводить, делайте его коротким и проверяйте количество абзацев в каждом фрагменте. Если проверить не можете, не отправляйте его.

Ошибка 3: фрагмент, отправленный отдельно, дал персонажу неверную роль

Запуск A отправлял каждый фрагмент без глоссария и без контекста. Для первых пяти фрагментов это хорошо работало: Prokurist стал «старшим клерком» во всех 16 местах, где он появлялся. Шестой фрагмент был единственным абзацем, в котором старший клерк отчитывает Грегора через дверь. Увиденный отдельно, модель перевела der Prokurist как «коммивояжёр», то есть собственная должность Грегора. Количество абзацев совпало, а соотношение длины было 1,00, так что ни одна структурная проверка этого не заметила.

В запуске B, где глоссарий был в системной инструкции, а предыдущий абзац — в контексте, тот же абзац правильно использовал «старшего клерка». Этот тест не может сказать, что именно из двух исправило дело. Поскольку контекст также вызвал ошибку 2, глоссарий — более безопасное место для переноса имён и ролей от фрагмента к фрагменту: он короткий, находится в инструкции, и его можно проверить механически.

Рабочий процесс, который выдержал проверку

1. Сначала извлеките из файла простой текст

Локальная LLM переводит текст, а не файлы. Преобразуйте документ перед началом:

  • DOCX или EPUB: экспортируйте в простой текст или Markdown, по одному абзацу на блок, сохраняя заголовки отдельными строками.
  • PDF с текстовым слоем: извлеките текст, затем исправьте разорванные строки и переносы. Наше руководство по исправлению разрывов строк и переносов после OCR описывает ту же очистку. Конвертер, такой как Docling, может создавать Markdown из PDF и файлов Office.
  • Сканированный PDF: сначала выполните OCR. Если вы не уверены, есть ли в PDF пригодный для использования текст, см. Извлечение текста из PDF vs OCR.

Сохраняйте структуру абзацев без изменений. Каждая последующая проверка зависит от взаимно однозначного соответствия между исходными и переведёнными абзацами.

2. Отключите режим размышления и подтвердите это

Многие современные открытые модели рассуждают, прежде чем ответить. При переводе это тратит время и выходные токены. В нашей настройке тестовый запрос на 200 токенов потратил 199 токенов на рассуждения и вернул пустой ответ.

Мы попробовали три распространённых переключателя. Добавление /no_think в промпт ничего не дало, и chat_template_kwargs с enable_thinking: false ничего не дало. Отправка "reasoning_effort": "none" в запросе отключила рассуждения: в ответе было указано 0 токенов рассуждений, и перевод вернулся напрямую. Этот параметр не указан на странице chat completions LM Studio, поэтому считайте это поведением, которое мы наблюдали в версии 0.4.8 с этой моделью. Проверяйте количество reasoning_tokens в своих собственных ответах, а не полагайтесь на какой-либо переключатель.

3. Определите размер контекстного окна до разбиения на фрагменты

Контекстное окно должно вмещать инструкцию, фрагмент и полный перевод. В наших запусках с разбиением на фрагменты немецкий фрагмент объёмом от 500 до 670 слов использовал примерно от 800 до 1 500 входных токенов в зависимости от глоссария и контекста и от 640 до 870 выходных токенов, поэтому нескольких тысяч токенов достаточно. Единственный запрос на 3 179 слов потребовал 4 953 входных токена и 3 930 выходных токенов.

Ollama устанавливает длину контекста по умолчанию в зависимости от доступной памяти: 4 тыс. токенов при объёме видеопамяти менее 24 ГиБ, 32 тыс. от 24 до 48 ГиБ и 256 тыс. при 48 ГиБ и более, согласно её документации по длине контекста, проверенной 23 октября 2026 года. Вы можете увеличить её с помощью OLLAMA_CONTEXT_LENGTH. В LM Studio задайте длину контекста при загрузке модели. Если фрагмент вместе с его переводом не помещается, вывод может быть обрезан.

4. Разбивайте на фрагменты по границам абзацев, примерно по 600 слов

Никогда не разрывайте абзац или предложение. Наши фрагменты были нацелены на 700 слов и заканчивались на ближайшей границе абзаца, что дало шесть фрагментов объёмом от 243 до 667 слов. Меньшие фрагменты стоят немного: запуск A занял 10,4 минуты против 9,5 минуты для единственного запроса, а неудачный фрагмент дёшево запустить повторно.

Держите инструкцию короткой и одинаковой для каждого фрагмента. Наша была такой: перевести на английский, сохранить ровно один выходной абзац на каждый входной абзац, разделённый пустой строкой, и выводить только перевод. Добавьте глоссарий в ту же инструкцию: одна строка на имя, титул или повторяющийся термин в форме Prokurist = chief clerk. Наше руководство по созданию глоссария для перевода описывает, что включать. Короткие фрагменты теряют окружающую историю, и именно глоссарий её несёт.

5. Проверяйте каждый фрагмент перед объединением

Выполните три проверки для каждого фрагмента:

  1. Количество абзацев. В выводе должно быть столько же абзацев, сколько во входе. Это выявило ошибку 2.
  2. Соотношение длины по абзацам. Сравните количество слов в каждом переведённом абзаце с исходным. Это выявило ошибку 1, которую проверка количества абзацев пропустила.
  3. Термины глоссария по абзацам. Там, где встречается исходный термин, его требуемый перевод должен встречаться столько же раз. Это выявило ошибку 3, которую пропустили обе другие проверки. Для языков с флексией здесь потребуется некоторое суждение, поскольку немецкий или русский термин меняет форму.

Для немецкой прозы, переведённой на английский, абзацы запуска A оставались в диапазоне от 0,98 до 1,17 выходных слов на входное слово. Повреждённый абзац запуска C составил 0,82. Установите свой собственный диапазон, проверив несколько абзацев, которым вы доверяете в вашей языковой паре; значения по умолчанию в нашем скрипте — это отправная точка, а не стандарт.

Абзац, помеченный флагом, — это место, где нужно читать в первую очередь, а не доказательство ошибки. Затем прочитайте сам перевод, особенно имена, числа, отрицания и всё, на что читатель будет опираться. Контрольный список проверки перевода книг описывает эту проверку.

6. Восстановите документ

Модель возвращает текст. Заголовки, сноски, таблицы, изображения, макет страницы и стили должны быть восстановлены вручную или с помощью инструмента конвертации. Для короткого отчёта это мелочь. Для книги со сносками и таблицами это может занять больше времени, чем перевод.

Сколько времени занимает целая книга

Наш запуск с разбиением на фрагменты перевёл 3 179 слов за 10,4 минуты, примерно 300 слов в минуту на этой машине. При такой скорости роман на 90 000 слов потребует примерно пяти часов генерации, не считая проверок и повторных запусков. Это простая арифметика из одного запуска, а не бенчмарк. Скорость меняется в зависимости от размера модели, квантования, оборудования, языковой пары и того, насколько ещё загружена машина.

Файл модели занимал 17,5 ГБ на диске, а кэш контекста и буферы времени выполнения требуют памяти сверх этого, поэтому машине нужно заметно больше свободной памяти, чем размер файла. Меньшая модель будет работать быстрее и на меньшем объёме памяти, обычно с некоторой потерей качества. Протестируйте её на репрезентативной выборке, прежде чем браться за целую книгу. Наше руководство по лучшей LLM для перевода объясняет, как составить такую выборку и справедливо сравнить модели.

Локальная LLM или служба перевода документов

ВопросЛокальная LLMСервис перевода документов
Может ли файл покинуть вашу машину?Не требуетсяТребуется
Что получаете на выходеПростой текст, который вы собираете самиПереведённый файл
Размер моделиОграничен вашей памятьюОграничен провайдером
Согласованность по всей книгеВаша задача: глоссарий, разбиение на фрагменты, проверкиВстроено в некоторые сервисы
Стоимость за документВаше оборудование и времяЦена за документ или за слово

Если ваши правила позволяют загружать файл, сервис перевода документов снимает большую часть работы, описанной выше. BookTranslator переводит целые файлы PDF, EPUB и DOCX и возвращает переведённый файл, а в его FAQ сказано, что загруженные файлы и результаты перевода не используются для обучения ИИ-моделей. Это облачный сервис, поэтому он не подходит, когда файл должен оставаться на вашей машине. Если вы выбираете между запуском моделей самостоятельно и оплатой сервиса, сколько на самом деле стоит перевод с помощью LLM показывает, как спланировать бюджет по токенам.

Получить тестовые файлы

Все файлы находятся в папке /files/blog/translate-with-local-llm/:

  • local_llm_translation_test.py: полный тест с локальным API LM Studio, включая все три запуска. Укажите другую модель или исходный текст, чтобы повторить тест.
  • check_translation.py: сравнивает исходный текст и перевод абзац за абзацем и выводит несовпадения количества абзацев, коэффициенты длины вне допустимого диапазона и отсутствующие термины глоссария (с --term "Prokurist=chief clerk"). Работает с результатами любого инструмента.
  • results.csv: каждый запрос с количеством абзацев, слов, токенов и временем.
  • failure-examples.txt: немецкий исходный текст и необработанный вывод модели для всех трёх сбоев.

Запустите check_translation.py с терминами вашего глоссария для любого длинного перевода, прежде чем полагаться на него. Это занимает секунды, и в этом тесте он выявил все три ошибки. Он не может сказать, верно ли звучит беглая фраза, поэтому отмеченные абзацы — это то, с чего начинается ваша вычитка, а не то, чем она заканчивается.

Похожие статьи