MAATRIX / Блог / Перевод документов на своём сервере без облака

Перевод документов на своём сервере без облака

Перевод документов на своём сервере без облака

MAATRIX

Юрист получает пачку из сорока договоров на английском и час на то, чтобы понять, что там написано. Бухгалтер — финансовую отчётность контрагента, которую нельзя показывать никому за пределами компании. Клиника — медицинские заключения пациентов на другом языке. Первый рефлекс — открыть Google Translate или вставить текст в ChatGPT. Второй, если в компании есть хоть кто-то из безопасности или юротдела, — вопрос: а куда физически уходят эти данные и что с ними делает сервис после того, как выдал перевод? Ответ обычно неприятный. Решение не в отказе от ИИ-перевода, а в том, чтобы вынести его на сервер, которым управляете вы: там же модель, там же файлы, никакого стороннего API между документом и переводом.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Почему облачные переводчики — риск для конфиденциальных документов

Условия использования бесплатных переводчиков почти всегда оставляют сервису право хранить и анализировать переданный текст. У Google Translate и аналогичных сервисов пользовательское соглашение допускает использование введённых данных для улучшения продукта — это прямо написанные пункты, которые никто не читает до момента, пока конфиденциальный контракт не окажется на серверах третьей стороны. У платных API ситуация лучше, но не идеальна: данные всё равно покидают периметр компании, проходят через инфраструктуру провайдера, иногда сохраняются для отладки моделей на срок от нескольких часов до нескольких месяцев в зависимости от тарифа.

Для типового текста это не страшно. Для документов с NDA, для финансовой отчётности перед сделкой, для персональных медицинских данных, для судебных материалов — это прямое нарушение обязательств перед клиентом, а в случае персональных данных россиян ещё и потенциальный конфликт со 152-ФЗ, если данные вообще не должны покидать определённую юрисдикцию.

Второй риск — доступность. Бесплатный переводчик может обрезать длинный документ, зависнуть на пакетной обработке, ввести капчу посреди работы; у платного API есть лимиты запросов и отказ в обслуживании в моменты пиковой нагрузки — как раз тогда, когда нужно перевести документы к дедлайну. Свой сервер с локальной моделью не имеет ни одной из этих зависимостей: работает столько, сколько нужно, и ровно с той скоростью, которую даёт железо.

Разумный компромисс — держать перевод рутинных внутренних документов и черновиков на своей инфраструктуре, а для действительно чувствительных случаев (нотариальный перевод, документы для суда) — обращаться к сертифицированному переводчику-человеку. Об этом подробнее в последнем разделе.

Какие открытые модели реально хорошо переводят

Ошибка, которую совершают почти все, кто только начинает разбираться в теме, — искать специализированную MT-модель (machine translation), что-то вроде классических NLLB, M2M100 или Marian. Эти модели существуют, но по факту современные универсальные LLM обгоняют их по качеству перевода на большинстве языковых пар, особенно там, где важен контекст, идиомы и стиль, а не дословная подстановка слов.

На конец августа 2026 для перевода документов на своём сервере разумно смотреть на:

  • Qwen2.5 / Qwen3 (7B–32B) — сильные модели с широким покрытием языков, включая русский, английский, китайский и большинство европейских языков. Хорошо держат юридическую и деловую лексику.
  • Llama 3.x / Llama 4 — уверенный английский и основные европейские языки, русский заметно слабее, чем у Qwen.
  • Модели семейства Gemma — компактные, быстрые, подходят для менее требовательных задач и ограниченного железа.
  • Специализированные fine-tune под перевод (например, модели на базе Mistral, дообученные под конкретную языковую пару) — если ваш кейс — это в основном одна пара языков, узкая дообученная модель иногда даёт более стабильный результат, чем универсальная.

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

Из практики: для связки русский/английский/европейские языки на 16–24 ГБ видеопамяти комфортно работает Qwen2.5-32B-Instruct в 4-битном кванте; для более скромного железа — Qwen2.5-14B или 7B с некоторой потерей качества на сложных формулировках. Если видеокарты нет, крупные модели тянет и CPU-инференс, просто медленнее — разбор того, какая модель Ollama влезет в конкретный объём памяти, есть в материале сколько RAM нужно для Ollama.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Развернуть Ollama

Установка Ollama и выбор модели под перевод

Ollama — самый быстрый способ поднять локальную модель без ковыряния в Python-зависимостях. Ставится одной командой на Ubuntu/Debian:

curl -fsSL https://ollama.com/install.sh | sh
sudo systemctl enable --now ollama

Проверка, что сервис поднялся и слушает порт:

systemctl status ollama
curl http://127.0.0.1:11434/api/tags

По умолчанию Ollama слушает только 127.0.0.1 — это правильно для сервера, где перевод дёргается локальным скриптом. Наружу порт 11434 открывать не нужно, если только вы намеренно не строите распределённую схему с отдельным клиентом.

Дальше — модель. Для задачи перевода берём инструкционную версию, а не базовую:

ollama pull qwen2.5:32b-instruct-q4_K_M
# для более скромного железа
ollama pull qwen2.5:14b-instruct-q4_K_M
ollama pull qwen2.5:7b-instruct-q4_K_M

Быстрая проверка на одном предложении перед тем, как запускать пакетную обработку:

ollama run qwen2.5:32b-instruct-q4_K_M "Переведи на английский язык, сохрани деловой стиль: Настоящий договор вступает в силу с момента подписания сторонами."

Если ответ выглядит разумно и не обрезан — можно переходить к промптам под реальные документы. Если Ollama на сервере уже стоит и знакома в общих чертах — базовая установка и типовые проблемы разобраны в материале как поднять локальный запуск LLM через Ollama на сервере.

Промпт-инжиниринг для перевода документов

Главная проблема "наивного" промпта вида "переведи этот текст" — модель начинает вести себя как редактор, а не переводчик: сокращает длинные абзацы, добавляет пояснения в скобках, переформулирует канцелярит в разговорную речь, теряет нумерацию пунктов. Для документов это недопустимо: юридический текст должен сохранять структуру и терминологию, а не становиться "более понятным".

Рабочий шаблон промпта для перевода формального документа:

Ты — профессиональный переводчик юридических и деловых документов.
Переведи текст ниже с {язык_источника} на {язык_цели}.

Правила:
1. Переводи дословно и точно, не добавляй пояснений, комментариев
   и вводных фраз от себя.
2. Сохраняй структуру документа: нумерацию пунктов, абзацы,
   переносы строк точно как в оригинале.
3. Юридические и финансовые термины переводи устоявшимися
   эквивалентами в целевом языке, а не буквально.
4. Если термин не имеет однозначного эквивалента — оставь
   оригинал в квадратных скобках после перевода.
5. Не переводи имена собственные, названия компаний и номера
   договоров — оставь как в оригинале.
6. Не добавляй никакого текста до или после перевода —
   в ответе должен быть только переведённый текст.

Текст для перевода:
---
{текст_документа}
---

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

Для длинных документов важно не превышать разумный размер куска: модели с окном 32–128К токенов формально способны проглотить весь договор целиком, но на практике качество на большом объёме падает — модель теряет согласованность терминологии между началом и концом. Разумный компромисс — резать документ на блоки по 1500–3000 токенов (примерно 1–2 страницы) и передавать модели глоссарий ключевых терминов в системном промпте, чтобы термин "существенное условие" переводился одинаково во всех кусках.

Пакетная обработка через скрипт

Переводить документы по одному вручную через ollama run не масштабируется дальше десятка файлов. Правильный путь — обращаться к Ollama через её HTTP API и гонять папку файлов скриптом. Ниже — рабочий пример на Python, который берёт все .txt-файлы из папки, режет их на куски и переводит через локальный эндпоинт:

import os
import re
import requests

OLLAMA_URL = "http://127.0.0.1:11434/api/generate"
MODEL = "qwen2.5:32b-instruct-q4_K_M"
SRC_DIR = "documents/source"
DST_DIR = "documents/translated"
SRC_LANG = "русский"
DST_LANG = "английский"

PROMPT_TEMPLATE = """Ты — профессиональный переводчик юридических и деловых документов.
Переведи текст ниже с {src_lang} на {dst_lang}.

Правила:
1. Переводи дословно и точно, без пояснений и комментариев от себя.
2. Сохраняй структуру: нумерацию пунктов, абзацы, переносы строк.
3. Термины переводи устоявшимися эквивалентами.
4. Не переводи имена собственные и номера договоров.
5. В ответе — только переведённый текст, без вводных фраз.

Текст для перевода:
---
{text}
---"""

def split_into_chunks(text, max_chars=6000):
    paragraphs = text.split("\n\n")
    chunks, current = [], ""
    for p in paragraphs:
        if len(current) + len(p) > max_chars and current:
            chunks.append(current)
            current = p
        else:
            current += ("\n\n" if current else "") + p
    if current:
        chunks.append(current)
    return chunks

def strip_preamble(text):
    # срезаем типовые вводные фразы, если модель их всё же добавила
    patterns = [
        r"^Вот перевод[^:]*:\s*",
        r"^Перевод:\s*",
        r"^Here is the translation[^:]*:\s*",
        r"^Translation:\s*",
    ]
    for p in patterns:
        text = re.sub(p, "", text, flags=re.IGNORECASE)
    return text.strip()

def translate_chunk(text):
    prompt = PROMPT_TEMPLATE.format(src_lang=SRC_LANG, dst_lang=DST_LANG, text=text)
    response = requests.post(OLLAMA_URL, json={
        "model": MODEL,
        "prompt": prompt,
        "stream": False,
        "options": {"temperature": 0.2}
    }, timeout=300)
    response.raise_for_status()
    return strip_preamble(response.json()["response"])

def translate_file(src_path, dst_path):
    with open(src_path, "r", encoding="utf-8") as f:
        text = f.read()
    chunks = split_into_chunks(text)
    translated_chunks = [translate_chunk(c) for c in chunks]
    with open(dst_path, "w", encoding="utf-8") as f:
        f.write("\n\n".join(translated_chunks))

def main():
    os.makedirs(DST_DIR, exist_ok=True)
    files = [f for f in os.listdir(SRC_DIR) if f.endswith(".txt")]
    for i, filename in enumerate(files, 1):
        print(f"[{i}/{len(files)}] {filename}")
        src_path = os.path.join(SRC_DIR, filename)
        dst_path = os.path.join(DST_DIR, filename)
        try:
            translate_file(src_path, dst_path)
        except Exception as e:
            print(f"  ошибка: {e}")

if __name__ == "__main__":
    main()

Температура 0.2 в примере выбрана намеренно низкой: для перевода не нужна творческая вариативность, нужна предсказуемость и повторяемость. Скрипт логирует прогресс по файлам — на пачке из полусотни договоров это полезно, чтобы видеть, где обработка встала, если один из файлов вызвал ошибку.

На сервере с одной видеокартой имеет смысл гонять скрипт последовательно, а не параллельными запросами — Ollama по умолчанию держит одну модель в памяти и обрабатывает запросы в очереди, так что распараллеливание на уровне скрипта просто создаст очередь на стороне сервера без выигрыша в скорости.

Работа с форматированными документами: docx и pdf

Реальные документы редко приходят в виде голого .txt — это .docx с таблицами и стилями или .pdf со сканами и версткой. Прямой перевод "как есть" через LLM здесь не работает: модель видит только текст, а разметку, шрифты, таблицы и расположение на странице нужно восстанавливать отдельно. Это отдельная техническая задача, но подход стандартный:

  1. Извлечение текста. Для .docx — библиотека python-docx, которая даёт доступ к параграфам и таблицам как к структурированным объектам. Для .pdfpdfplumber или PyMuPDF для документов с текстовым слоем; для сканов сначала нужен OCR, например pytesseract или PaddleOCR.
  2. Перевод по абзацам или ячейкам, а не всего документа одним куском — это сохраняет привязку переведённого текста к месту, куда его нужно вставить обратно.
  3. Обратная вставка. Для .docxpython-docx позволяет заменить текст параграфа, сохранив форматирование, если работать с объектом paragraph.runs, а не пересоздавать параграф с нуля. Для .pdf обратная вставка сложнее: если важна вёрстка — проще сгенерировать новый файл из переведённого текста через .docx как промежуточный формат, чем редактировать PDF напрямую.
  4. Таблицы и колонтитулы — отдельная головная боль: их легко потерять при наивном извлечении, поэтому для документов с таблицами (финансовая отчётность, спецификации) их стоит обрабатывать как отдельную структуру, а не сливать в общий текстовый поток.

Если объём документов со сложной вёрсткой большой и регулярный, конвейер извлечение → перевод → вставка обычно оформляют отдельным сервисом на сервере, который принимает файл на вход и отдаёт переведённый на выходе, используя тот же локальный Ollama-эндпоинт. Для смежной задачи — извлечения и структурирования содержимого документов без выноса в облако — см. ИИ-анализ документов на сервере.

Контроль качества: где заканчивается ИИ и начинается человек

Локальный ИИ-перевод решает задачу конфиденциальности и масштаба, но не заменяет квалифицированного переводчика там, где на кону юридическая сила документа. Три случая, где машинный перевод — только черновик, а не финальный результат:

  • Нотариально заверенный перевод. Для подачи документов в госорганы, посольства, суды требуется перевод, выполненный и заверенный дипломированным переводчиком, часто с последующим нотариальным заверением подписи. ИИ здесь не участник процесса в принципе — юридически значим только человек с соответствующей квалификацией.
  • Договоры с материальными последствиями. Ошибка модели в переводе условия о неустойке, сроке или юрисдикции спора может стоить реальных денег. ИИ-перевод такого документа — основа для дальнейшей работы юриста, а не готовый к подписанию текст.
  • Медицинские и клинические данные. Неверно переведённая дозировка или диагноз — это риск для здоровья, а не просто неловкость. Здесь черновой перевод ускоряет работу врача или переводчика-специалиста, но не заменяет его финальную проверку.

Практический процесс, который работает: ИИ переводит первый черновик, человек — редактор или профильный специалист — вычитывает результат, сверяя термины и цифры, особенно даты, суммы и номера пунктов, которые модель иногда меняет местами при сбое генерации. Экономия времени сохраняется — редактировать готовый перевод в разы быстрее, чем переводить с нуля, — а ответственность за итоговый текст остаётся на человеке, который его подписывает.

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

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Развернуть Ollama

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Частые вопросы

Нужна ли видеокарта для перевода документов через Ollama?

Нет, но она сильно ускоряет процесс. Модели 7B–14B в 4-битном кванте переводят абзац за несколько секунд и на CPU современного сервера, просто медленнее, чем на GPU. Для разовой обработки полусотни документов CPU вполне достаточно; для постоянного потока в сотни страниц в день видеокарта окупается временем.

Можно ли доверять локальной модели перевод контракта на серьёзную сумму?

Как черновик — да, как финальный документ для подписания — нет. Используйте ИИ-перевод, чтобы понять содержание и ускорить работу юриста, но финальную версию для подписания или подачи в суд должен проверить и заверить человек-специалист.

Какая модель лучше всего переводит на русский язык?

На конец августа 2026 семейство Qwen2.5/Qwen3 стабильно даёт более качественный русский, чем Llama 3.x. Но однозначного ответа "на все случаи" нет — для вашей конкретной языковой пары и типа документов стоит прогнать тестовый набор абзацев через 2–3 модели и сравнить руками, прежде чем ставить процесс на поток.

Что делать, если модель обрывает длинный документ на середине?

Скорее всего упёрлись в контекстное окно модели или лимит num_predict в запросе к Ollama. Режьте документ на более мелкие куски (1500–3000 токенов) и увеличьте num_predict в параметрах запроса — по умолчанию Ollama может ограничивать длину генерации.

Стоит ли переводить сразу весь docx-файл одним запросом к модели?

Нет — модель работает с текстом, а не со структурой файла. Извлекайте текст по абзацам или ячейкам таблиц, переводите каждый кусок отдельно и вставляйте обратно с сохранением форматирования — это надёжнее, чем пытаться прогнать весь файл целиком.

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.