Обновить
79
Ogoun@Ogoun

.NET + DE/ML

19
Подписчики
Отправить сообщение

В конечном виде, это webui поверх питоновских скриптов, в котором можно создавать и глоссарии и переводы. Если говорить о полном пайплайне и технической стороне, то ниже собрал опусом как это выглядит.

Полный пайплайн перевода

Дано: **английская книга**, которую надо перевести, и **референсный русский перевод** другой книги того же цикла (образец стиля). Нужно: русский перевод новой книги, звучащий как этот образец.

Главная идея: модель ничему не обучается. Стиль, имена и знание мира подаются модели в контексте — примерами из референсного перевода, карточками персонажей и глоссарием. Поэтому «переучивать» ничего не надо: поменял референс — поменялся стиль.

Общая картина

   английская книга          референсный русский перевод
          │                              │
          ├──────────────┬───────────────┤
          ▼              ▼               ▼
   ┌─────────────┐  ┌──────────────────────────┐
   │  ГЛОССАРИЙ  │  │     КОРПУС СТИЛЯ         │
   │ кто есть кто│  │ пары «абзац EN ↔ абзац RU»│
   └──────┬──────┘  └────────────┬─────────────┘
          │                      │
          └────────┬─────────────┘
                   ▼
          ┌──────────────────┐
          │     ПЕРЕВОД      │  черновик главы → редактура →
          │                  │  проверка связности
          └────────┬─────────┘
                   ▼
        русский перевод (md + fb2) + отчёт о полноте

Три больших этапа: глоссарий, корпус стиля, перевод. Первые два делаются один раз на цикл книг, третий — на каждую книгу.

Этап 1. Глоссарий: система узнаёт, кто есть кто

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

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

Шаг 1.1. Разбор файлов на главы и сцены

Инструмент: собственные парсеры + разбиение по типографским разделителям (* * *, смена времени/места). Книга превращается в аккуратный список глав и сцен внутри них. Опционально границу сцены умеет искать модель эмбеддингов (paraphrase-multilingual-mpnet-base-v2) — для текстов без разделителей.

Шаг 1.2. Поиск имён и названий (NER)

Модели: ансамбль из трёх.

  • GLiNER multi v2.1 (на базе mdeberta-v3-base) — многоязычный поиск сущностей по описанию классов;

  • FABLE-base — модель, дообученная на художественной прозе (персонажи, локации, объекты, события);

  • Natasha (slovnet) — для русских текстов.

Три списка находок объединяются в один: пересекающиеся упоминания склеиваются, каждому остаётся лучший вариант.

Шаг 1.3. Уточнение через LLM (самый долгий шаг)

Модель: большая языковая модель на локальном сервере — по умолчанию Qwen3.5-27B в кванте Q5 (на мощном железе — модель крупнее). Инструмент: llama.cpp или vLLM как OpenAI-совместимый сервер.

Текст режется на окна, и по каждому окну модель отвечает строгим JSON: кто здесь действует, какие альтернативные имена и прозвища, признаки (пол, вид, титул, роль). Формат ответа принудительный (грамматика JSON).

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

Шаг 1.4. Сшивка одной сущности по всем файлам

Инструмент: трёхуровневый матчер (точное совпадение → нормализованные формы → нечёткое сходство) + скоринг канонического имени. «Erin», «Erin Solstice» и «трактирщица» сводятся к одному персонажу с одним каноническим именем и списком псевдонимов.

Шаг 1.5. Кто говорит и кого имеют в виду

  • Атрибуция реплик: LLM определяет говорящего у прямой речи.

  • Кореференция (что значит «она» в этом абзаце): Maverick (модель maverick-mes-litbank, запускается изолированным процессом), а если она недоступна — та же LLM по сегментам.

Шаг 1.6. События и изменения признаков

Модель: LLM. Извлекается, что произошло и что изменилось: «в 42-й главе волосы стали белыми», «в 120-й получила титул». Каждое изменение помечается номером главы — так строится временная линия персонажа.

Шаг 1.7. Профиль речи персонажа

Модель: LLM + контрастный промпт (реплики героя против реплик остальных). Получается описание манеры речи: формальность, словечки-паразиты, любимые фразы, подсказка о регистре в русском.

Шаг 1.8. Таблица перевода имён

Инструменты: сначала автоматика — сопоставление с найденными в русском референсе именами и нечёткая транслитерация; что не сошлось — отдаётся LLM. Сомнительные строки помечаются «на проверку».

Шаг 1.9. Оценка качества имеющегося перевода

Модель: wmt22-cometkiwi-da (на базе infoxlm-large) — оценка качества перевода без эталона. Даёт ориентир по нескольким парам абзацев.

Шаг 1.10. Поисковый индекс и граф (по желанию)

Инструменты: chonkie (нарезка на чанки), эмбеддинги mpnet, локальный Qdrant (векторный поиск), NetworkX + PageRank (граф связей — кто с кем и насколько важен).

Шаг 1.11. Сборка и 8 автопроверок

Всё складывается в дерево YAML-карточек + сводная статистика. Затем глоссарий устанавливается в проект и компилируется в один машинный файл — «мастер», которым дальше пользуется перевод. При установке в него автоматически подтягиваются переводы имён и профили речи; поверх кладутся ручные правки пользователя.

Итог этапа: база знаний по циклу, где к каждой главе известно ровно то, что известно читателю на этой главе.

Этап 2. Корпус стиля: система учится «звучанию» переводчика

Задача: получить много пар «абзац оригинала → абзац эталонного перевода». Именно эти пары потом показываются модели как образец: «вот так этот переводчик передаёт иронию, вот так оформляет диалог».

Вход — английский оригинал и референсный русский перевод одной и той же книги.

Шаг 2.1. Разбор книг

Инструменты: парсеры fb2 / epub / html / md / txt (BeautifulSoup, lxml, ebooklib). Обе книги превращаются в markdown по главам.

Шаг 2.2. Сопоставление глав

Модель: эмбеддинги paraphrase-multilingual-mpnet-base-v2 (понимает смысл текста независимо от языка). Английская глава сопоставляется со своей русской: по смыслу и по эвристикам заголовков. Лишние и непарные главы отбрасываются.

Шаг 2.3. Сопоставление абзацев внутри пары глав

Модель: те же эмбеддинги. Алгоритм: динамическое программирование (как выравнивание последовательностей). Учитывается, что переводчик мог склеить два абзаца в один или разбить один на два. На выходе — список пар абзацев с оценкой уверенности.

Итог этапа: файл выравнивания (на полном корпусе — тысячи пар). Делается один раз на референсный перевод.

Этап 3. Перевод новой книги

Здесь работает одна большая языковая модель на локальном сервере — та же Qwen3.5-27B класса и выше; конкретная модель и размер контекста подбираются автоматически по объёму видеопамяти (пресеты: 24 ГБ / 48 ГБ / 70+ ГБ / 110+ ГБ). Программа сама печатает готовую команду запуска сервера под ваше железо.

Локально при этом грузятся только вспомогательные модели (эмбеддинги для подбора примеров), вся видеопамять отдана серверу.

Шаг 3.1. Разбор книги

Инструмент: те же парсеры. Книга → список глав с абзацами.

Шаг 3.2. Подготовка контекста для главы

Перед переводом главы собирается «досье»:

  • Блок глоссария — канонические имена персонажей и терминов, но только тех, кто уже появлялся к этой главе (без спойлеров).

  • Карточки персонажей — для каждого, кто встречается в главе: пол, вид, титулы, характер, манера речи, важные приметы и «что изменилось за последние главы». Всё — по состоянию на эту главу.

  • Связи и события — кто кому кем приходится, что недавно произошло.

  • Примеры стиля (few-shot) — из корпуса второго этапа подбираются несколько пар «оригинал → эталонный перевод», максимально похожих на текущую главу. Инструмент: эмбеддинг-индекс (mpnet) + отбор по методу MMR (берёт похожие, но разные между собой примеры, а не пять почти одинаковых). Индекс строится один раз и кэшируется.

Шаг 3.3. Черновик — вся глава за один запрос

Модель: LLM на сервере.

Глава подаётся целиком, абзацы пронумерованы; модель обязана вернуть перевод с той же нумерацией. Почему целиком: так модель видит всю сцену разом и держит единые имена, местоимения, время и тон — при переводе кусочками эти вещи «плывут» на стыках.

Ответ проверяется: все ли абзацы на месте, не оборвался ли текст. Если глава не влезает в контекст — она делится пополам и так далее; если что-то пошло не так — повторный запрос, в крайнем случае перевод по частям. Температура низкая (0.3): при высокой модель начинает «сочинять» вместо перевода.

Шаг 3.4. Нарезка на фрагменты для редактуры

Инструмент: собственный чанкер, режущий по границам сцен (разделители, смена времени, переход диалог↔описание), около 1200 слов на фрагмент.

Шаг 3.5. Редактура каждого фрагмента (обязательный шаг)

Модель: LLM на сервере, в роли литературного редактора.

Редактору дают оба текста сразу — английский оригинал и русский черновик — плюс карточки персонажей и хвост предыдущего переведённого фрагмента (чтобы род и время не сбивались на стыке). Задача не переводить заново, а править: тяжёлые кальки, рассогласование рода, пропущенные детали, оформление диалогов, лексические повторы.

Есть страховки: если редактура оборвалась или вернула подозрительно короткий текст — берётся черновик, и это видно в логе.

Шаг 3.6. Автоматическая доводка имён и диалогов

Инструмент: регулярные выражения по глоссарию (без модели). Оставшиеся английские имена заменяются каноническими русскими; кавычки прямой речи приводятся к тире. Замены тоже ограничены главой — будущие персонажи не всплывают.

Шаг 3.7. Ревизор (по желанию)

Модель: LLM на сервере. Смотрит сразу на несколько готовых подряд фрагментов и ищет то, что не видно внутри одного: героиню назвали то «она», то «он»; имя написано двумя способами; кусок фразы потерялся. Найденное отправляется на повторную редактуру уже с конкретным замечанием.

Шаг 3.8. Сборка результата

Инструмент: собственный сборщик. Главы складываются в один markdown и в fb2 (готовый файл для читалки). Каждая глава дополнительно лежит отдельным файлом.

Шаг 3.9. Проверка полноты смысла

Модель: wmt22-cometkiwi-da — оценивает качество перевода, сверяя его с оригиналом, без всякого эталона.

Фрагменты с оценкой ниже порога (0.60) отправляются на один повтор редактуры с прямым указанием, что содержание потерялось. Итог — отчёт с оценками по всем фрагментам.

Что происходит при сбоях

Перевод книги — это часы, сборка глоссария — сутки. Поэтому:

  • Каждый готовый фрагмент сразу пишется на диск. Перезапуск продолжает с места, уже переведённое не переводится заново.

  • Сборка глоссария возобновляема на уровне отдельного окна.

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

  • Полный провал не выдаётся за успех: если не переведено ничего (например, сервер лежал), задача честно помечается как упавшая.

Кто чем занят — краткая таблица

Шаг Что делает Модель / инструмент Разбор книг файлы → главы BeautifulSoup, lxml, ebooklib Поиск имён находит персонажей и места GLiNER multi v2.1 (mdeberta), FABLE-base, Natasha Уточнение сущностей кто есть кто, псевдонимы, признаки Qwen3.5-27B (llama.cpp / vLLM) Кто говорит атрибуция реплик и местоимений Qwen3.5-27B + Maverick (litbank) События и изменения временная линия персонажей Qwen3.5-27B Профиль речи манера речи героя Qwen3.5-27B Перевод имён таблица EN → RU транслитерация + Qwen3.5-27B Оценка качества скор без эталона wmt22-cometkiwi-da (infoxlm-large) Поиск по смыслу индекс чанков chonkie + mpnet + Qdrant Граф связей важность и родство персонажей NetworkX + PageRank Сопоставление глав/абзацев пары «оригинал ↔ перевод» mpnet + динамическое программирование Подбор примеров стиля few-shot к главе mpnet + MMR Черновик главы перевод всей главы разом Qwen3.5-27B и выше (по видеопамяти) Редактура фрагмента правка по оригиналу та же LLM в роли редактора Канонизация имён замены по глоссарию регулярные выражения Ревизор связность между фрагментами та же LLM Сборка md + fb2 собственный сборщик Контроль полноты что потерялось по смыслу wmt22-cometkiwi-da

Что нужно сделать один раз, а что — на каждую книгу

Один раз на цикл: глоссарий (этап 1) и корпус стиля (этап 2). На каждую книгу: только этап 3.

Что менять, если результат не нравится:

  • звучит не как референс → корпус стиля (больше/чище пары, больше примеров в промпт);

  • путаются имена и титулы → правки в глоссарии;

  • теряется содержание → порог проверки полноты и повторная редактура;

  • «плывут» род и время между кусками → контекст соседних абзацев и ревизор.

Делаю тоже самое, но на локальных моделях, и тоже из за книги (захотел перевести полностью блуждающий трактир, 12 мегабайт чистого текста). Глоссарий заложен с первой версии, сейчас он еще и таймлайн включает, то есть как меняется что либо со временем, у героя может смениться имя, или речь. Изначально делал дополнительный шаг для обучения лоры на существующем переводе, чтобы подхватывать стиль переводчика, но сейчас это выкинул. Также вначале использовал gemma 4 и qwen, сейчас остался только qwen, который работает в нескольких ролях (переводчик, корректор, оценщик качества и т.п.). Пока основной минус - время, на построение глоссария - 3 недели и пара месяцев на перевод. Но это на слабом железе, если арендовать H200, то за трое суток по расчетам должно отработать всё, в ближайших планах это проверить.

Гоняю на RTX3090, 15 секунд генерятся где то 450 секунд времени. 0.4Mpx. Ну и как уже сказали в соседнем комментарии, модель int8_convrot.

Если нужна идентификация, почему не сделать ее возможной. Я пытаюсь пройти уже месяц, и она проваливается потому что контактные данные не совпадают с данными на госуслугах. Я заводил домены до того как альтернативно одаренные люди начали рулить рунетом, и не было необходимости указывать настоящие данные. Сейчас, чтобы сохранить домены, я согласен их указать, но при исправлении контактов ничего не происходит (reg.ru), через длительное ожидание ответа от поддержки, внезапно оказалось что исправление контактов не то чем кажется, и исправлять можно только если сменился паспорт, чтобы указать новый. А самое интересное, чтобы исправить контакты нужно написать заявку, в которой я должен напискать текст, что я изначально указывал заведомо ложные данные (оператор техподдержки несолько раз подряд делал на этом акцент). Ложные относительно чего? На момент указания не было даже госуслуг. В общем, требуете пройти идентификацию, и сами же не дали адекватного способа это сделать. Ну в про время ответа от поддержки уже писали, реально ждать неделями приходится.

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

Может есть опыт или знание, что брать для дремеля чтобы можно было работать с камнем? А именно с твердыми породами.

Есть отлично кастомизируемый MoonReader, пользуюсь им много лет, пока ни одного минуса не находил.

Вот что показал анализ 10000 ссылок опусом 4.7:

Структура расшифрована. r= декодируется в 50 байт (или 66 для размер-варианта): PREFIX(18) + FILE_ID(16) + SUFFIX(16). Гипотеза «суффикс универсален» ошибочна — это album_id, разный для разных альбомов. Префикс — per-tenant, в наборе их 4.

Проведены тесты на предсказуемость FILE_ID (на чистой выборке 3 542 ID одного альбома):

  • GF(2)-ранг битовой матрицы = 128/128 (аффинный 129/129) — линейных/аффинных зависимостей нет

  • Парный χ² между байтами 125–212 при пороге 270 — корреляций нет

  • Хэммингово расстояние между ID: среднее 63.8 (ожидаемое 64) — равномерное

  • Sort-and-diff: средний интервал ровно 2¹²⁸/N — без счётчика

  • Никаких таймстемпов (UUIDv7/ULID/Snowflake), никакой структуры от хеша короткого входа

Единственная аномалия: у одного из тенантов байт 0 файла принимает 192/256 значений (зарезервированы диапазоны 0x48–0x67 и 0xb0–0xcf). Это даёт всего −0.41 бита энтропии — остаётся ~2¹²⁷·⁶. Видимо, серверная партиционная разметка, а не дефект ГСЧ; не воспроизводится в других тенантах.

Существующий scanner/scanner.py принципиально бесполезен. При ~10⁴ файлах в системе вероятность попадания случайным os.urandom(16) ≈ 3·10⁻³⁵; при заявленных 7 000 req/s ожидание первого попадания ≈ 10²³ лет. Те «hits», что у него есть, — это зашитый VALIDATION_ID. Превзойти его аналитически невозможно: предсказать FILE_ID по другим валидным URL нельзя.

Перевел родителей на него для созвонов, вполне устраивает. Плюс созваниваемся с тиммейтами в играх, тоже норм. Из минусов только то что нельзя каждому собеседнику отдельно громкость задавать.

Негосударственные тоже не лучше, например, участвовал в хакатоне по играм, собрал за два дня вполне рабочий прототип, несколько других команд собрали тоже вполне играбельное. А в итоге победителя выбирали по аплодисментам, и победила команда с девушкой нацепившей хвост лисы..
В серьезном государственном на много миллионов тоже участвовал, обнаружили серьезное нарушение от команды которая в итоге победила, однако организаторы закрыли глаза на их нарушение и пропустили. Причем нарушено было два правила за каждое из которых дисквалифицируют.
Больше не пробую, сил и времени уходит немеряно, а побеждают те кто нашел обходные пути или договорился.

Не хватает проверки на нужные приложения, например, попробовал на чистом новом дебиане, ругается на отсутствие xxd.

Допуск в свою корпоративную серверную стороннего персонала без присутствия своего персонала при этом - ну такое....

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

Я даже на секунду поверил про совместимость. Но нет, MSVC 2022, cmake, gcc, Clang не могут собрать простой код написанный на c++ версии 1985 года. Например, они не знают откуда брать <stream.h> поддержка которого была удалена.

Пример кода, первое что в голову пришло
#include <stream.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>

char* digit_names[] = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };

main(int argc, char* argv[])
{
    if (argc != 2) {
        cerr << "Usage: " << argv[0] << " <filename>\n";
        return 1;
    }
    char* in_path = argv[1];
    FILE* fin = fopen(in_path, "r");
    if (fin == 0) {
        cerr << "Error: File " << in_path << " not found or cannot be opened.\n";
        return 1;
    }
	
    int name_len = strlen(in_path) + 7;
    char* out_path = new char[name_len]; 
    strcpy(out_path, in_path);
    strcat(out_path, ".fixed");

    FILE* fout = fopen(out_path, "w");
    if (fout == 0) {
        cerr << "Error: Cannot create output file " << out_path << "\n";
        fclose(fin);
        delete out_path;
        return 1;
    }
    cout << "Processing file: " << in_path << "\n";
    cout << "Output file: " << out_path << "\n";

    int count = 0;
    int c;

    while ((c = fgetc(fin)) != EOF) {
        if (isdigit(c)) {
            int index = c - '0';
            fputs(digit_names[index], fout);
            count++;
        } else {
            fputc(c, fout);
        }
    }
    fclose(fin);
    fclose(fout);
    delete out_path; 
    cout << "Done. Replaced " << count << " digits.\n";
    return 0;
}

Тут, возможно, помогли бы готовые проекты типа SuperGlue, чтобы заматчить статичные участки фона, и SAM, чтобы сегментировать отдельные участки.

Если людей хорошо лечить, то им и пенсии платить придется.

Всего то нужно достать чьи то зарубежные наработки и адаптировать к нашим условиям (как с гигачатом).

Я делал утилиту которая перемешивает содержимое всех файлов со случайными данными. После такого восстановить исходные данные уже не выйдет.

Еще бы докинуть kinopub, soap и подобные сервисы, которые через VPN тоже работают значительно лучше чем rutube и vk без него.

В Яндексе, умные люди?! Эти слова нельзя ставить в одном предложении. Есть там пара хороших продуктов (кликхаус, например), но в остальном чисто маркетинговые сырые поделки, с нерабочим API.

1
23 ...

Информация

В рейтинге
5 070-й
Откуда
Москва, Москва и Московская обл., Россия
Дата рождения
Зарегистрирован
Активность

Специализация

Бэкенд разработчик, Архитектор программного обеспечения
Старший
От 600 000 ₽
C#
Microsoft SQL Server
.NET Core
WPF
.NET
ASP.NET
Базы данных
MongoDB