Числа в переводе документа: как не потерять код и сумму
Неуклюжая фраза в переведённой таможенной декларации стоит одного перечитывания. Неверная цифра в коде ТН ВЭД стоит развёрнутой поставки. Эти два отказа разделены порядками величины по последствиям — и ничем вообще в любой метрике качества, которую вы, скорее всего, гоняете.
BLEU не отличает число от прилагательного. COMET тоже, и LLM, оценивающая беглость и адекватность, тоже: перевод, потерявший регистрационный код компании, может получить 100, потому что как текст он в порядке. Если вы переводите документы, числовую целостность нужно мерить отдельно, детерминированно и показывать самостоятельным числом.
Ниже — как это делаем мы, включая два способа, которыми мы испортили саму проверку, прежде чем она заработала.
Почему общие метрики тут бессильны
Метрики качества устроены так, чтобы поощрять язык, сохраняющий смысл. Число — не язык. У него нет синонимов, нет допустимого пересказа и нет частичного зачёта: 2537143416 и 2537143415 одинаково неверны и одинаково беглы.
Хуже того, отказ невидим со стороны вывода. Декларация, где уцелели 27 чисел из 28, читается ровно так же, как та, где уцелели все 28. Никто не заметит, пока не заметит принимающий инспектор.
Значит, проверка обязана быть сравнением, а не суждением. Сравнения дёшевы, детерминированы и не способны выдумать справку о здоровье.
Проверка и первый способ её испортить
Наивная реализация токенизирует оба текста и сравнивает токены, похожие на числа. Она сообщает о потерях, которых нет.
Причина — пунктуация. В исходнике значение стоит в середине фразы как 2537143416,, а в переводе завершает строку как 2537143416. Потокенно это разные строки, и проверка рапортует о пропавшем числе и о лишнем появившемся. На плотном бланке этот шум хоронит настоящие находки, а проверка, которой не верят, — это проверка, которую не запускают.
Лечение — сравнивать максимальные цепочки цифр, вынутые регуляркой, а не токены:
исходник: "код 2537143416, дата 02.07.2026"
цепочки: 2537143416, 02, 07, 2026
Выбросить всё, что не цифра, взять самые длинные непрерывные последовательности и сравнить эти мультимножества. Пунктуация, кавычки, скобки и переносы строк перестают иметь значение — чего мы и добиваемся: ни одно из них не является частью числа.
Второй способ испортить: даты
Как только сравниваются цепочки цифр, даты немедленно дают ложные тревоги — потому что даты и есть тот единственный класс чисел, который перевод документа обязан менять.
20260702 в китайской декларации становится 02.07.2026 в русском выводе. Это верное поведение: целевая локаль пишет даты иначе. Для сравнения цепочек это одно исчезнувшее число и три появившихся.
Значит, датам нужен свой путь: распознать, привести обе стороны к канонической форме и сравнить как даты. Всё остальное сравнивается как сырые цепочки, где любое изменение — дефект.
Общий принцип стоит проговорить, потому что он шире дат: проверка обязана знать, какие преобразования законны. Проверка, помечающая верное поведение, приучает людей себя игнорировать, а это хуже, чем её отсутствие.
Как числа выглядят на живом документе
Один полный прогон, китайская экспортная таможенная декларация в перевод на русский:
| Отслежено исходных чисел | 28 |
| Вышли без изменений | 26 |
| Намеренно переформатировано (дата) | 1 |
| Потеряно по-настоящему | 1 |
Единственная настоящая потеря — самая интересная. Строка грузоотправителя в исходнике: (91330206MAD62XJF0Y)(33029600GQ) — два кода компании, а не один. Схема извлечения объявляла одно поле. Первый код сохранился, второму некуда было деться, а вывод выглядел полным.
Такова форма большинства числовых потерь на документах, заполняемых по шаблону, и о ней стоит сказать точно: модель прочитала значение верно, а у формы не оказалось графы. То есть числовая целостность — свойство не только перевода. Это свойство схемы и бланка, и проверка ловит все три отказа разом: не прочитали, перевели неверно, некуда положить.
Третий способ испортить: сама линейка
Самый дорогой урок оказался не про числа. Он про инструмент, который их мерил.
Мы построили харнесс, чтобы оценивать извлечение против эталона, и он сообщил о 24 пропущенных значениях на пачке документов. Настоящим не было ни одно.
Харнесс сравнивал сырой ответ модели с эталоном. Боевой путь делает то, чего харнесс не делал: он выравнивает и нормализует payload до валидации — уплощает сгруппированный вывод, сопоставляет имена, — так что значения, которые харнесс видел отсутствующими, в бою были доставлены. Измерение оценивало пайплайн, которого не существует.
Урок, применимый к любой написанной вами проверке: линейка обязана идти тем же путём, что и прод. Проверка, пропускающая нормализацию, которую прод выполняет, будет сообщать об отказах, невоспроизводимых никем, — и команда научится не читать отчёт, а именно в этот момент сквозь него и проскочит настоящий дефект.
Куда ставить проверку
Три места, и они отвечают на разные вопросы:
После извлечения, против исходного текста. Прочитали ли мы все числа со страницы? Ловит потери OCR и промахи vision.
После перевода, исходные значения против целевых. Пережило ли перевод каждое число? Ловит классическую ошибку перевода и выпавшую цифру.
После рендеринга, извлечённые значения против готового документа. Дошло ли каждое число до вывода? Вот эта ловит «у формы не было графы», и её-то большинство пайплайнов и не делает.
Если можете позволить себе одну — берите третью. Она ближе всех к тому, что получает заказчик, и включает в себя остальные: число, потерянное где угодно выше по течению, отсутствует и здесь.
Как отчитываться, чтобы по отчёту действовали
Числовая проверка даёт счёт, а счёт действеннее оценки. Три правила, к которым мы пришли:
- Показывать отдельно от качества. Не свёрнутым в композитный балл, где 100 за беглость маскирует потерянный код. Два числа рядом.
- Называть значения, а не только счёт. «Потеряно одно число» — метрика; «
33029600GQесть в исходнике и отсутствует в выводе» — баг-репорт. - Отличать переформатированное от потерянного. У них разное лечение — одно правило локали, другое дефект, — и слияние делает метрику бесполезной в обе стороны.
Главное
- Ни одна общая метрика качества не видит числовой потери. Перевод без кода ТН ВЭД читается безупречно и оценивается соответственно; проверка обязана быть отдельной и детерминированной.
- Сравнивайте максимальные цепочки цифр, а не токены. Приклеенная пунктуация заставляет токенное сравнение сообщать о несуществующих потерях, а шумная проверка — это проверка игнорируемая.
- Даты — законное исключение и требуют своего нормализованного сравнения; проверка, помечающая верное поведение, учит себя не читать.
- Большинство настоящих потерь на бланках — это «некуда положить». Значение прочитано верно, а поля в целевой форме нет, — то есть числовая целостность есть и свойство схемы.
- Заставьте линейку идти путём прода. Наша сообщила о 24 пропусках, и все они были артефактом нормализации, которую харнесс пропускал, а прод выполняет.
FAQ
Почему BLEU или COMET не ловят неверное число?
Потому что они меряют язык, сохраняющий смысл, а число — не язык. У него нет синонимов и нет частичного зачёта: изменённая цифра так же бегла, как неизменённая, и метрика не видит ничего.
Как на самом деле проверять числовую целостность?
Сравнивая максимальные цепочки цифр между исходником и переводом как мультимножества, с отдельным распознаванием и нормализацией дат, которые законно меняют форму. Это детерминированное сравнение, стоит нисколько и даёт счёт плюс конкретные значения.
Почему цепочки цифр, а не токены?
Потому что пунктуация к числам приклеивается. 2537143416, и 2537143416 — разные токены и одно и то же число, поэтому токенное сравнение выдаёт ложную потерю и ложное добавление на каждое число рядом с запятой. Этот шум хоронит настоящие находки.
А если число переформатировано законно?
Обрабатывайте даты отдельным путём — распознать, нормализовать обе стороны, сравнить как даты, — а всё остальное считайте точным. Переформатированное и потерянное показывайте раздельно: первое это верно работающее правило локали, второе — дефект.
На каком месте пайплайна запускать проверку?
В идеале трижды: после извлечения, после перевода и после рендеринга. Если запускаете один раз — запускайте последней: сверка извлечённых значений с готовым документом ловит всё, что выше по течению, плюс случай, когда под значение в целевой форме не оказалось поля.
Заключение
Числовая целостность — редкое свойство качества, которое одновременно дёшево измерить и дорого испортить, и потому его стоит инструментировать в документном пайплайне первым. Это сравнение, а не суждение: без вызова модели, без порога, без исследования корреляций.
Трудным оказалась не проверка, а дисциплина вокруг неё: сравнивать то, что нужно, разрешать законные преобразования и следить, чтобы измерение шло тем же путём, что и прод. Ошибитесь в этом — и получите отчёт, полный призрачных отказов, а именно так и остаётся незамеченным настоящий.
Если вы переводите декларации, свидетельства или выписки и хотите видеть числовую целостность отдельным числом, — попробуйте KTTC.
