Shanraq.org Shanraq.org
IT

AI без LLM: создаем свою модель ИИ Урок 30 из 30

Урок 30. Выпускаем консольную модель и проверяем выводы

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

Зачем это нужно

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

Перед кодом

Скопируйте из папки шага 30 все пять файлов: main.py, engine.py, checks.py, facts.json, examples.json. Команда получает дату и вопрос: кавычки сохраняют вопрос с пробелами как один аргумент. Необязательное --trace ставится перед датой и печатает путь решения. sys.argv хранит аргументы; len выбирает одну из двух допустимых форм команды. sys.exit(2) завершает неправильный вызов с кодом ошибки. try пробует превратить текст даты в календарную дату, except ValueError перехватывает неверный формат и выдаёт понятное сообщение. Дата — день, на который спрашивают, а не утверждение, что учебная запись верна сейчас.

Файлы этого шага: examples.json, checks.py, engine.py, facts.json, main.py.

Из корня проекта перейдите в папку шага и запустите программу:

cd course/kazakh-ai/step-30
python3 main.py 2026-09-24 "Шахмат қашан?"

В Windows замените python3 на py.

import sys
from datetime import date

from engine import answer

if len(sys.argv) == 3:
    show_trace = False
    raw_date = sys.argv[1]
    question = sys.argv[2]
elif len(sys.argv) == 4 and sys.argv[1] == "--trace":
    show_trace = True
    raw_date = sys.argv[2]
    question = sys.argv[3]
else:
    print('Қолдану: python3 main.py [--trace] YYYY-MM-DD "Сұрақ"')
    sys.exit(2)
try:
    on_date = date.fromisoformat(raw_date)
except ValueError:
    print("Қате күн: YYYY-MM-DD түрінде жазыңыз")
    sys.exit(2)
result = answer(question, on_date)
print(result["text"])
if show_trace:
    for line in result["trace"]:
        print("Із:", line)

Файлы шага.

Что делает программа

Из папки шага выполните python3 main.py 2026-09-24 "Шахмат қашан?": получите шахмат үйірмесінің уақыты: бейсенбі, 15:00 | 2026-09-24 күнгі дерек | дереккөз: club-sheet-01. На Сурет қайда? — білмеймін: дерек жоқ; на Шахмат қашан қайда? — просьба выбрать один вид; на дату 2027-01-01 — отказ из-за срока. Добавьте --trace для пяти шагов проверки источника. Контрольный набор из урока 25 оценивал только тип вопроса и был мал; он не доказывает качество реальной службы. Мы показали локальную узкую модель, не универсальный ИИ. Нулевые платные API-запросы в учебном коде не означают нулевую полную стоимость; отсутствие свободной генерации не делает ошибку источника невозможной.

Паспорт готовой модели

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

python3 benchmark.py --json

Холодный запуск начинается с нового процесса Python. Тёплый запрос выполняется внутри уже работающего процесса. p95 — граница, быстрее которой завершились 95 процентов запросов. RSS — наибольшая физическая память всего процесса; tracemalloc считает только наблюдаемые выделения Python. Обучаемый параметр — число, которое нейросеть меняет при обучении. У нашей системы таких чисел нет: счётчик намерений строится из 13 карточек при запуске.

Пропускная способность показывает, сколько запросов выполняется за секунду. Один рабочий процесс — одна запущенная копия Python, которая в нашем опыте выполняет по одному запросу за раз и использует не больше одного ядра одновременно. Затем программа прогревает 1, 2, 4 и 8 процессов, трижды даёт каждому по 10 000 запросов и берёт средний по порядку результат. КиБ равен 1024 байтам, а МиБ — 1024 КиБ. ARM — семейство процессоров компьютера, на котором сделан контрольный замер.

Контрольный запуск 25 сентября 2026 года на ARM-компьютере с macOS 26.5.2 и Python 3.14.5 дал:

На телефоне сдвигайте следующие широкие таблицы пальцем влево и вправо.

Что измерено Результат
Обучаемые нейронные параметры 0
Учебные карточки / утверждённые факты 13 / 2
Доступные логические ядра / рабочие процессы / запросы одновременно 8 / 1 / 1
Код и рабочие данные модели 6 907 байт (6,7 КиБ)
Медиана холодного запуска 34,682 мс
Медиана тёплого запроса / p95 0,034 / 0,037 мс
Пропускная способность одного последовательного процесса 42 520 запросов/с
Пиковые выделения tracemalloc 135 626 байт
Пиковая RSS всего Python-процесса 25 608 192 байта (24,4 МиБ)
Все сценарии / правильные ответы на известные факты 16 из 16 / 6 из 6
Правильные отказы 10 из 10
Уверенный ответ там, где нужен отказ 0 из 10
Внешние API-запросы 0
Прямая плата API 0; устройство, электричество и труд не равны нулю
Энергия на запрос не измерена: нужен аппаратный счётчик мощности

Что дали дополнительные процессы

Ускорение сравнивает общую скорость с одним рабочим процессом. Параллельная эффективность делит ускорение на число процессов: 100% означали бы, что каждый новый процесс добавил полную долю скорости. Суммарная RSS ниже складывает пики рабочих процессов; память управляющего процесса в неё не входит.

Рабочие процессы Запросы одновременно Общая скорость, запросов/с Ускорение Эффективность Сумма пиков RSS
1 1 42 953 1,00 раза 100% 25,4 МиБ
2 2 80 372 1,87 раза 93,6% 50,8 МиБ
4 4 146 241 3,41 раза 85,1% 101,7 МиБ
8 8 141 357 3,29 раза 41,1% 204,0 МиБ

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

Последняя строка качества — наша измеримая замена расплывчатому слову «галлюцинация». Здесь ошибка означает: эталон требовал отказа, а программа уверенно выдала иной ответ. 0 из 10 относится только к опубликованным проверкам. Оно не доказывает нулевую ошибку на любом тексте и не защищает от неверного факта в facts.json.

Сопоставление с большими LLM

У закрытых GPT, Claude и Gemini разработчики не публикуют число весов и память серверов. Поэтому утверждение, что «все параметры всех основных LLM известны», неверно. Для открытых моделей масштаб опубликован; память зависит от точности весов и способа запуска.

Сохранённое значение параметра называют весом. FP8 и BF16 — два способа хранить вес: примерно в 1 или 2 байтах. Поэтому там, где число параметров известно, нижнюю оценку легко повторить умножением. Это только веса; рабочая память, кэш контекста и служебные данные добавляются сверху. Токен — слово или часть слова, на которые LLM делит текст; контекст — набор токенов, доступных ей в одном запросе. Знак ≈ далее означает расчётную, а не измеренную на нашем компьютере величину.

Система Опубликованный масштаб Память или размер Те же 16 проверок
Наша учебная модель 0 нейронных параметров; 13 карточек; 2 факта измерено: 6 907 байт файлов; 24,4 МиБ RSS одного процесса с Python измерено: 16/16; ошибочный уверенный ответ 0/10
Llama 3.1 405B 405 млрд параметров; контекст 128 тыс. токенов ≈405 ГБ FP8 или ≈810 ГБ BF16: в 58,6–117 млн раз больше наших файлов не запускалась на нашем наборе
DeepSeek-V3 671 млрд всего, 37 млрд работают на одном токене; контекст 128 тыс. ≈671 ГБ FP8 или ≈1,342 ТБ BF16: в 97–194 млн раз больше; рабочая память сверху не запускалась на нашем наборе
Qwen3-235B-A22B 235 млрд всего, 22 млрд активных ≈235 ГБ FP8 или ≈470 ГБ BF16: в 34–68 млн раз больше; рабочая память сверху не запускалась на нашем наборе
GPT-5.6 Sol / Gemini 3.7 Flash параметры и серверная RAM не раскрыты; контекст около 1 млн токенов по открытым данным не вычисляется: контекст и цена не определяют число весов не запускались на нашем наборе

По объёму файлов порог «в тысячу раз» для размера выбранных представлений здесь пройден с большим запасом. Этот коэффициент нельзя переносить на интеллект, число задач, скорость или качество: LLM работает со свободным текстом и множеством задач, а наша модель знает два вида вопросов и два факта. Скорость LLM мы тоже не подменяем чужой цифрой: для честного отношения надо прогнать конкретную версию на том же оборудовании или через зафиксированный API и на тех же 16 запросах.

Источники масштаба: Meta о Llama 3.1 405B и контексте 128K, карточка DeepSeek-V3, требования NVIDIA для DeepSeek-V3, описание Qwen3, официальные характеристики GPT-5.6, официальные характеристики Gemini 3.7 Flash.

Где наша модель сильнее, а где уступает

Сравнение нужно для выбора инструмента. Карманный калькулятор быстрее человека умножает числа, но не пересказывает книгу; библиотекарь понимает свободный вопрос, но поиск занимает больше ресурсов. Так же различаются наша модель и LLM.

Свойство Наша детерминированная модель Большая LLM Вывод для проекта
Узкие утверждённые факты возвращает только запись из справочника и показывает источник может составить свободный правдоподобный текст наша модель лучше там, где ответ обязан совпасть с утверждённой карточкой
Ошибка вне границы отказывает по явной причине может ответить, но фактическую опору надо проверять отдельно отказ полезнее догадки при высокой цене ошибки
Скорость и ресурсы этой задачи измерены локально: килобайты файлов, миллисекунды и десятки МиБ вместе с Python большие веса или удалённый API узкая модель выгоднее для маленького фиксированного справочника
Свободная речь и широкий круг тем не умеет умеет объяснять, обобщать, переводить и работать с разными формами запроса LLM намного сильнее в открытых задачах
Новое слово и перефразирование требует нового правила или примера часто понимает без изменения программы наша модель хуже переносит незнакомые формулировки
Обновление знаний человек правит небольшой проверяемый файл знания весов нельзя исправить одной карточкой; можно подключить поиск или базу у нашей модели проще точечная проверка, но справочник надо вести вручную
Повторяемость одинаковые код, данные и вход дают тот же путь и ответ результат зависит от версии, настроек и обслуживающей системы нашу узкую модель проще воспроизвести побайтно
Передача запроса учебный код не обращается к сети облачный API получает запрос; локально развёрнутая LLM может оставить его на устройстве преимущество зависит от способа развёртывания, а не только от вида модели
Проверяемость решения путь можно повторить строка за строкой внутренний путь огромной сети нельзя полностью проследить наша модель прозрачнее в своей узкой области
Масштаб задачи два намерения, два факта и несколько известных словоформ много языков, тем и форматов результат 16/16 нельзя переносить за пределы учебного набора

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

Правило выбора можно восстановить по трём вопросам:

  1. Набор фактов мал, утверждён и цена выдумки высока? Начните с детерминированной модели.
  2. Пользователь просит работать со свободным текстом и заранее нельзя перечислить все формулировки? Рассмотрите LLM и отдельную проверку фактов.
  3. Нужны оба свойства? Измерьте смешанную систему на одном закрытом наборе, а не складывайте обещания двух технологий.

Опорная карта

Команда + дата + вопрос → охрана слов → тип → одна карточка → допустимая дата → ответ и источник; иначе объяснимый отказ.

Опорная схема урока 30

Вспомните и проверьте

Закройте код и восстановите цепочку из опорной карты. Проверьте четыре команды: известный вопрос, неизвестный кружок, старую дату и --trace. Подсказка: дата 2026-09-24 попадает между checked_on и valid_until, а 2027-01-01 — уже нет. Эталон для старой даты: білмеймін: бұл күнге жарамды дерек жоқ; для неизвестного кружка: білмеймін: таныс емес сөз. Частая ошибка: назвать дату упражнения текущим расписанием реального клуба.

Рубеж 6: итоговая защита

Покажите, что ответ связан с карточкой и сроком; получите тот же ответ для Шахмат қашан? и известной формы Шахматтың уақыты қашан?; назовите два честных отказа; запустите паспорт и объясните разницу между RSS и выделениями Python. Затем объясните, почему 16/16 не означает безошибочность и почему коэффициент размера нельзя переносить на интеллект. Рубеж пройден, если вы можете провести нового человека по цепочке без текста урока. При затруднении вернитесь к соответствующей из шести опор, затем защитите проект повторно.

Если вы нашли ошибку или опечатку в тексте статьи, то сообщите нам об этом

Комментарии (0)

Пока нет комментариев. Будьте первым.