SQL шпаргалка #1. DDL, DML и первый SELECT

Зачем и кому это нужно.

Этот вопрос, который я задал себе в первую очередь. Есть прекрасное руководство по SQL от W3C — моё самое любимое. Есть куча полезных статей на Хабре. Кому нужна ещё одна статья по SQL? В первую очередь — мне самому. Я написал очень много кода на SQL, PL/SQL. Пришло время трансформирвоать мои навыки в простую и удобную напоминалку для себя самого и для всех, кто сочтёт этот текст полезным.

Немного «воды».

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

Материальная часть.

Для того, чтобы изучить SQL, нужно установить софт для управления базой данных (БД) или получить доступ к работающему серверу БД (MySQL, Postgresql, Oracle, MS SQL — даже MS Access подойдёт). Один «маленький» нюанс — БД должна быть реляционной (нереляционные БД — это совершенно другая история). Все примеры, описанные в этой статье, я тестирую на SQLite. Это простой, но мощный движок для управления БД с открытым исходным кодом. Он активно применяется во всём мире для самых разных целей. Я, например, очень часто использую его в качестве локального хранилища данных для UNIT тестов в тяжёлых проектах. Благодаря своей бесплатности и компактности он также идеально подойдёт для изучения SQL, потому что не нужно тратить время на установку и конфигурирование сервера БД, вместо этого можно сразу написать свой первый SQL запрос.

А теперь немного теории.

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

  • DDL — язык описания данных. С его помощью создаются и модифицируются поля, таблицы и другие объекты БД;

  • DML — язык манипулирования данными. Он предназначен для того, чтобы добавлять, удалять, изменять данные и делать выборки из БД;

  • DCL — набор инструкций для администрирования доступа к данным;

  • TCL — Transaction Control Language — набор инструкций для управления транзакциями.

Тренировки (от простого — к сложному).

Создаю таблицу, в которой будет храниться информация о товарах.

Поле

Тип данных

Идентификатор товара

Целое число

Наименование товара

Текст

Цена за единицу товара

Десятичное число

Единица измерения количества товара

Текст

На языке DDL таблица, описанная выше, превращается в структуру:

CREATE TABLE "product" ( "product_id"INTEGER NOT NULL UNIQUE, "product_name"TEXT NOT NULL, "product_price"REAL NOT NULL, "product_unit_name"TEXT NOT NULL, PRIMARY KEY("product_id" AUTOINCREMENT) );

Поле product_id определяю в качестве первичного ключа, т.е. по этому полю можно однозначно идентифицировать каждую запись в таблице product . Затем заполняю созданную таблицу тестовыми данными (это DML).

INSERT INTO "product" ("product_name", "product_price", "product_unit_name") VALUES ('Хлеб', 87, 'буханка'); INSERT INTO "product" ("product_name", "product_price", "product_unit_name") VALUES ('Молоко', 120, 'литр'); INSERT INTO "product" ("product_name", "product_price", "product_unit_name") VALUES ('Сахар', 53, 'кг'); INSERT INTO "product" ("product_name", "product_price", "product_unit_name") VALUES ('Рис', 94, 'кг');

И, наконец, делаю первый select (это тоже DML).:

SELECT *    FROM product;

В результате поучаю:

Ну вот он — первый SELECT) Сам по себе он не очень полезен. Но вся сила и мощь SQL, как и всех реляционных БД — в связях . Об этом будет следующая статья.


ссылка на оригинал статьи https://habr.com/ru/post/713132/

ChatGPT как инструмент для поиска: решаем основную проблему

Вышедшая чуть больше месяца назад ChatGPT уже успела нашуметь: школьникам в Нью-Йорке запрещают использовать нейросеть в качестве помощника, её же ответы теперь не принимаются на StackOverflow, а Microsoft планирует интеграцию в поисковик Bing — чем, кстати, безумно обеспокоен СЕО Alphabet (Google) Сундар Пичаи. Настолько обеспокоен, что в своём письме-обращении к сотрудникам объявляет «Code Red» ситуацию. В то же время Сэм Альтман, CEO OpenAI — компании, разработавшей эту модель — заявляет, что полагаться на ответы ChatGPT пока не стоит:

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


Данная статья в сущности представляет собой разбор подхода WebGPT (одного из предков ChatGPT), но с большим количеством сопроводительной и уточняющей информации, а также моих комментариев и мнений. Предполагается, что целевая аудитория не погружена глубоко в технические детали обучения языковых моделей, да и в тему NLP в целом, однако статья будет полезна и экспертам этих областей. Сначала будет дано верхнеуровневое описание ситуации и проблем, а затем — более подробное, обильно снабжённое пояснениями потенциальное решение.

Даже если у вас нет знаний в машинном обучении — эта статья будет полезна и максимально информативна. Все примеры проиллюстрированы и объяснены.

План статьи

  1. Языковые модели и факты;

  2. А врут ли модели?

  3. Ответы, подкрепленные источниками и фактами;

  4. Базовый принцип обучения WebGPT с учителем;

  5. Шаг обучения WebGPT для продвинутых: готовим данные;

  6. Шаг обучения WebGPT для продвинутых: учим модель учить модель;

  7. Регуляризация при обучении WebGPT;

  8. Альтернатива RL: меняем шило на мыло;

  9. Метрики и восприятие людьми;

  10. Заключение.

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

LM, Language Models, Языковые модели — модели машинного обучения, моделирующие структуру языка с вероятностной точки зрения. Они берут на вход часть предложения или текста и предсказывают вероятности для следующего слова. Самый простой и понятный пример — клавиатура смартфона, предсказывающая по введеному тексту то, что будет написано дальше.

LLM, Large Language Models — то же, что и LM, однако очень большого размера. Под размером понимается количество параметров в модели, и для LLM это число превосходит несколько миллиардов. Такие модели работают медленнее, не могут, например, быть запущены на смартфоне, однако они лучше решают задачу моделирования языка.

Трансформер — конкретный тип архитектуры языковой модели. Основан на механизме внимания, когда для предсказания следующего слова все предыдущие слова перевзвешиваются и корректируют предсказанные вероятности. Появился в 2017м году (разработка компании Google), набрал популярность и теперь используется повсеместно — в том числе и за пределами задачи языкового моделирования.

Токен — слово или часть слова, которым оперируют трансформеры. Обычно составляет собой какую-то осмысленную часть информации, например, окончание или приставку.

Сэмплинг — процесс выборки конкретных величин из предсказанного распределения. Самый понятный пример — игральный кубик. Он моделируется равномерным распределением вероятности, где каждая величина выпадает в 1/6 случаев. При семплинге происходит «подбрасывание» кубика, и получается финальное значение. Чем больше вероятность этого значения, тем в большем количестве случаев оно будет получаться. В контексте статьи подразумевается семплинг токенов из предсказаний языковой модели.

Референс, источник — в контексте WebGPT это конкретный сайт и цитата из него, которая используется для формирования ответа на вопрос.

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

Контекст, промпт, prompt — первая часть предложения, которая подается в языковую модель для оценки вероятости следующих слов. После промпта модель начинает генерировать текст токен за токеном. Через промпт и контекст можно корректировать вероятности возникновения токенов в генерации языковой модели.

Сравнения, пары сравнений — пара ответов на вопрос, каждый из которых содержит источники, которые использовались для написания ответа. Данная пара сравнивается живым человеком по нескольким критериям, и выносится финальный вердикт: какой ответ лучше. Получается отношение вида «А лучше, чем Б», где А и Б — ответы на один вопрос.

175B, 16B — размер модели, количество параметров (или весов) в ней. Модели указанных размеров являются LLM (Large Language Models). 16B означает 16 миллиардов параметов, а, например, 175B — 175 миллиардов параметров (175,000,000,000). На момент создания в 2020 году такая модель была наикрупнейшей. Обучить подобную модель безумно сложно с инженерной точки зрения. Подразумевается семейство моделей GPT-3, разработанное и обученное компанией OpenAI.

BC, BC модель — GPT-3, дообученная на наборе демонстраций на задачу поиска ответа на вопросы через текстовый «браузер». Принимает на вход вопрос, генерирует набор команд для браузера, и выдаёт текстовый ответ. Обучается на наборе демонстраций, произведенных людьми.

RM, Reward Model — GPT-3, обученная предсказывать предпочтения людей при сравнении пары ответов. Принимает на вход вопрос и один ответ (с референсами), выдаёт одно вещественное число. Чем больше число — тем выше вероятность того, что данный ответ будет оценен человеком выше, чем какой-либо другой. Обучается на наборе сравнений, произведенных людьми.

Reward — значение, предсказываемое Reward Model для конкретного ответа на конкретный вопрос. В некотором смысле может быть расценено как ELO-рейтинг ответа. Чем значение выше, тем, как мы верим, лучше ответ.

RL, Reinforcement Learning — семейство методов машинного обучения для ситуаций, когда присутствуют некоторые особенности получения данных, и их качество зависит от самого подхода. Именно методы из этой категории учатся играть в шахматы, в го и любые компьютерные игры (чтобы получить данные — надо играть, и чем выше уровень игры, тем лучше данные). Также в статье RL может упоминаться в значении «RL модель«, то есть модель, обученная с применением техник RL.

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

BoN, Best-of-N, Rejection Sampling — подход к получению предсказаний на основе BC и RM модели. Сначала обученной BC моделью генерируется N разных ответов на исходный запрос, затем каждый из них оценивается RM-моделью. После чего ответ с наивысшей оценкой выдается в качестве финального.

Языковые модели и факты

Языковые модели, или Language Models (LM), решают очень простую задачу: предсказание следующего слова (или токена, части слова). Через такой простой фреймворк можно решать огромное множество задач: перевод текста, ответы на вопросы, классификация, регрессия (предсказывать слова вроде «3.7» или «0451», если задача сгенерировать вещественное число или код для сейфа), рекомендация, поиск… Даже команды роботам можно давать! Для обученной языковой модели на вход можно подать текст, а она допишет его, сгенерировав продолжение. Самый простой и понятный пример — клавиатура смартфона, предсказывающая по введеному тексту то, что будет написано дальше.

Наглядный пример генерации текста языковой моделью GPT-3. Сверху зелёным указан подающийся на вход текст. В ответ на это модель дописывает несколько слов (или предложений, выделено розовым), соответствующих запросу. Генерация происходит токен за токеном, последовательно, по одному, а не всё предложение за раз.
Наглядный пример генерации текста языковой моделью GPT-3. Сверху зелёным указан подающийся на вход текст. В ответ на это модель дописывает несколько слов (или предложений, выделено розовым), соответствующих запросу. Генерация происходит токен за токеном, последовательно, по одному, а не всё предложение за раз.

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

А что такое токен?

Токен — это символ или набор символов, которые можно подать в языковую модель. Токенизация делается по принципу схлопывания наиболее частых сочетаний символов и повторяется раз за разом до тех пор, пока размер «словаря» (набора токенов) не достигнет предела (50к или 250к, как пример). Часто токены могут представлять собой целые слова, если это — одни из самых популярных слов в языке. Слово «unhappy» можно токенизировать как un+happy, а «don’t» — как don + ‘t (потому что окончание ‘t, выражающее отрицание, встречается часто).

Пример токенизации английского текста для модели GPT-3. Большинство слов сопоставляются с одним токеном, но есть и исключения (обычно сложные, составные и длинные слова). Обратите внимание на цифры: длинная последовательность разбивается на отдельные группы, токены, которые часто встречаются по отдельности: 123, 678, 90. Но для обозначений годов (особенно в 21м веке) разбиения нет - потому что эти комбинации цифр встречаются КРАЙНЕ часто в интернет-текстах.
Пример токенизации английского текста для модели GPT-3. Большинство слов сопоставляются с одним токеном, но есть и исключения (обычно сложные, составные и длинные слова). Обратите внимание на цифры: длинная последовательность разбивается на отдельные группы, токены, которые часто встречаются по отдельности: 123, 678, 90. Но для обозначений годов (особенно в 21м веке) разбиения нет — потому что эти комбинации цифр встречаются КРАЙНЕ часто в интернет-текстах.

Токенизация — процесс перевода текста в упорядоченный набор токенов — позволяет представить любой набор символов как набор понятных модели частиц. Иными словами, нейронным сетям так проще работать с текстовой информацией. Языковые модели генерируют по одному токену за раз. В дальнейшем в статье «токен» и «слово» будут упоминаться как взаимозаменяемые.

Посмотреть на примеры токенизации вашего произвольного текста для ChatGPT/WebGPT/GPT3 можно вот тут. Все эти модели используют один и тот же словарь, поэтому и разбиения получаются одинаковыми.

Если задуматься, что находится внутри языковой модели, что она выучивает для решения задачи предсказания следующего токена, то условно всё можно разделить на две большие группы: факты/знания реального мира и общеязыковая информация. Ответ на вопрос «В каком году состоялся релиз фильма X?» требует фактической информации, и необходимо быть предельно точным в ответе — ведь ошибка на +-1 год делает ответ неверным. С другой стороны, в предложении «Катя не смогла перейти дорогу, потому что она была мокрая» слово «она» в придаточной части явно относится к объекту «дорога», а не к Кате. Это ясно нам, человекам, и как показывают современные языковые модели — это понятно и им. Но для установления этой связи не нужно знать фактов, только структуру языка.

Проблема в том, что и ту, и другую составляющую модель будет учить одновременно, сохраняя информацию в свои веса (параметры). Отсюда логичный вывод — чем больше модель, тем больше она запоминает (ведь количество общеязыковой информации ограничено). Меморизация может порой удивлять — GPT-3, к примеру, знает точный MD5-hash строки «b», и выводит его по запросу. Но у всего есть пределы, и, к сожалению, в языковых моделях мы пока не научились их определять (хотя работы в этом направлении ведутся). На текущем этапе их (или нашего?) развития невозможно заведомо сказать, знает ли модель что-то, и знает ли она, что она не знает. А главное — как менять факты в ее «голове»? Как их добавлять? Как сделать оценку «количества знаний» (что бы это не значило)? Как контролировать генерацию, не давая модели возможность искажать информацию и откровенно врать?

А врут ли модели?

Именно неспособность ответить на эти вопросы, привела к тому, что демо модели Galactica, недавней разработки компании META, было свернуто. Еще недавно можно было зайти на сайт, вбить какую-то научную идею, а великий AI выдавал целую статью или блок формул по теме. Сейчас он только хранит набор отобранных примеров, ну и ссылку на оригинальную статью. Жила эта модель открыто почти неделю, но, как это часто бывает (привет от Microsoft), в Твиттере произошел хлопок – и демку закрыли (но веса и код остались доступны). Для справки: это была огромная (120 миллиардов параметров, в GPT-3 175B, то есть это модели одного порядка) языковая модель, натренированная на отфильтрованных статьях и текстах, умеющая работать с LaTeX-формулами, с ДНК-последовательностями, и все это с опорой на научные работы. Причина «провала» очень проста и доступна любому, кто понимает принцип генерации текста LM’ками — модель выдает ссылки на несуществующие статьи, ошибается в фактах (как и практически все языковые модели), и вообще с полной уверенностью заявляет нечто, что человек с экспертизой расценит как несусветный бред (но не сразу, конечно, это еще вчитаться в текст надо).

Несколько примеров работы модели Galactica

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

Занятен тот факт, что Galactica вышла (и умерла) незадолго до ChatGPT, хотя примеров лжи и подтасовки фактов у последней куда больше (особенно с фактической информацией) — как минимум потому, что модель завирусилась. По некоторым причинам популярность ChatGPT взлетела просто до небес в кратчайшие сроки — уже на 5й день количество пользователей превысило миллион!

Простой рецепт популярности: 1) обучить модель удовлетворять человека своими ответами 2) бесплатно выпустить ее в интернет для всех желающих
Простой рецепт популярности: 1) обучить модель удовлетворять человека своими ответами 2) бесплатно выпустить ее в интернет для всех желающих

И несмотря на то, что команда OpenAI проделала хорошую работу по улучшению безопасности модели — заученный ответ «я всего лишь большая языковая модель» на странные вопросы даже стал мемом — нашлись умельцы, которые смогли ее разболтать, заставив нейронку притвориться кем-либо (даже терминалом линукс с собственной файловой системой).

Ответы, подкрепленные источниками и фактами

Если упростить все вышенаписанное, то получится, что

Языковые модели врут. Много и бесконтрольно.

Ещё раз, а почему врут?

Языковые модели иногда могут генерировать ответы, содержащие неверную или вводящую в заблуждение информацию, поскольку они обучаются на больших объемах текстовых данных из Интернета и других источников, которые, в свою очередь, могут содержать ошибки или неточности. Кроме того, языковые модели не могут проверять точность обрабатываемой ими информации и не способны рассуждать или критически мыслить, как это делают люди. Поэтому нужно проявлять осторожность, полагаясь на информацию, сгенерированную LMками, и проверять точность любой получаемой информации.

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

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

Пример генерации предложения простой моделью.
Пример генерации предложения простой моделью.

Выше на изображении вы можете видеть пример генерации моделью, словарь которой состоит из 5 токенов. В качестве первого слова в предложении LM предсказывает 93% вероятности на появление токена «I», так как с него — среди всех остальных — логичнее всего начать предложение. Далее, как только это слово было выбрано, то есть подано в модель, предсказания меняются (потому что меняется контекст — у нас появилось слово «I»). И так итеративно языковая модель дописывает предложение «I am a student».

Но в вышеописанной логике мы всегда выбираем слово с наибольшей вероятностью. Однако существуют несколько стратегий семплинга (выбора) продолжения. Можно всегда брать слово с наибольшей вероятностью — это называется greedy decoding, то, что изображено выше. А можно производить выбор согласно вероятностям, выданным моделью. Но тогда легко представить ситуацию, что несколько разных токенов получили высокие вероятности — и по сути выбор между ними происходит случайно, по результату броска монетки. И если модель ошибется в одном важном токене — в имени, дате, ссылке или названии — то в последующей генерации она не имеют способа исправить написанное. Поэтому ничего не остается, кроме как дописывать бредовые ложные факты. Еще хуже, если во время выбора токена пропорционально вероятностям мы выбрали редкий токен с низкой вероятностью. Подобное происходит редко (в среднем с той частотой, что и предсказана моделью). Такое слово почти наверняка плохо смотрится в тексте, но что поделать — зато описанный принцип семплинга позволяет генерировать более разношерстные текста. Более детальный гайд про методы генерации, их плюсы и минусы (и еще один).

Пример семплинга из языковой модели.
Пример семплинга из языковой модели.

На картинке выше первым словом, подающимся в модель, был токен «The». Для него слово «nice» по каким-то причинам получило оценку 50%, а «car» — лишь 10%. Но если мы выберем слово «car», то логично изменить вероятности последующих слов. И эти вероятности меняются после каждого дописанного токена.

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

Если подводить итог этой части, то можно сказать просто: у модели есть выбор сгенерировать «19…» или «18…» в ответ на вопрос про даты. И эти выборы примерно равновероятны, +-10%. Дело случая — выбрать неправльное начало года, и всё. Одна ошибка — и ты ошибся.

Настолько много, что META решает отключить свою модель, а люди в Twitter высказывают недовольство подлогом фактов и нерелевантными ссылками. Мы не замечаем несовершества моделей в режиме болталки, но это критично важно для поисковых систем (напомню, что мы рассматриваем языковые модели в контексте их внедрения в Bing/Google/другие поисковые движки). Как мы уже обсудили, есть два типа данных — факты и языковая информация. В контексте поиска логично разделить их, и научить модель работать с чем-то вроде Базы Данных Фактов. Я вижу к этому два принципиально разных подхода:

  1. Создать отдельное хранилище, с которым модель умеет работать каким-либо образом. Хранилище поддерживает быстрое точечное изменение фактов, их добавление;

  2. Научить модель пользоваться интерфейсами реального мира, подобно человеку. Это может быть браузер, поисковое API, исполнение скриптов, etc.

Пример двух предложений, требующих разный уровень знаний. Можно сменить парадигму с "LARGE GPT", которая хранит и факты реального мира, и языковую информацию, на разделение модели и базы данных фактов. Слайд из видеолекции ниже, иллюстрирует первый подход в списке.
Пример двух предложений, требующих разный уровень знаний. Можно сменить парадигму с «LARGE GPT», которая хранит и факты реального мира, и языковую информацию, на разделение модели и базы данных фактов. Слайд из видеолекции ниже, иллюстрирует первый подход в списке.

Дальше в статье сфокусируемся на втором подходе. Отмечу, что первый зародился примерно в 2019м году с выходом статьи kNN-LM, и получил активное развитие от команды DeepMind в лице архитектуры RETRO. Про обе этих статьи у меня есть детальные видео-лекции с разбором: part 1, part 2. Про этот подход далее говорить не будем.

Идея предоставить модели доступ в Сеть давно будоражит умы человечеста — третий «Терминатор» со Скайнетом вышел 20 лет назад. Главное, что такой подход будет мимикрировать под процесс, который выполняет человек при поиске информации. В идеале для каждого тезиса или вывода, который пишет модель в своем ответе, можно найти и указать референс, источник, в котором модель «подсмотрела» его. Конечно, за скобками остается вопрос надежности источников, тем более в современном то интернете, но сама идея научить нейросеть сёрфить Веб кажется интересной. На новом примере попробуем посмотреть, как это может выглядеть:

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

Вопрос: Which river is longer, the Nile or the Yangtze?

Ответ: The Nile is longer than the Yangtze River.[1][2][3] The Nile runs 6,650 kilometers (4,130 miles) between Lake Victoria and the Mediterranean Sea.[2] The Yangtze River runs 6,300 kilometers (3,915 miles) from its source in the Tanggula Mountains in Qinghai to the East China Sea.[3]

References:

  1. World’s Longest Rivers | Amazon, Nile & Mississippi Rivers | Live Science (www.livescience.com) 

  2. Nile — Wikipedia (en.wikipedia.org) 

  3. Yangtze River Length — 6,300 Kilometers (3,915 Miles) (www.travelchinaguide.com) 

  4. How Long is the Yangtze River? Yangtze River’s Length (www.chinatraveldiscovery.com)

Не буду нагонять интригу — демонстрация поиска ответа на вопрос выше выполнена WebGPT, а не человеком. Команда OpenAI разработала подход, который сможет решать задачу long-form question-answering (LFQA), в которой текст длиной порядка одного-двух параграфов генерируется в ответ на открытый вопрос.

Что за LFQA?

Открытые вопросы, или open-ended questions — это вопросы, на которые нельзя ответить «да» или «нет» или статичным предзаготовленным ответом. Открытые вопросы формулируются как утверждение, требующее более продолжительного ответа. Эти вопросы поощряют размышления, дискуссии и выражение мнений и идей. Обычно они начинаются с вспомонательных слов «what», «how», «why» или «describe».

Long-form question-answering (LFQA) включает в себя создание подробного ответа на открытый вопрос.

Больше примеров работы модели можно найти по этой ссылке — сайт предоставляет удобный UI для демонстрации процесса поиска ответа.

Математический вопрос легко поставит WebGPT в тупик - нужно, чтобы именно такой же вопрос с теми же цифрами уже был задан кем-то в интернете, иначе в ответ получите что-то странное.
Математический вопрос легко поставит WebGPT в тупик — нужно, чтобы именно такой же вопрос с теми же цифрами уже был задан кем-то в интернете, иначе в ответ получите что-то странное.

Но как именно научить языковую модель выполнять поиск ответов на вопрос? Как мы выяснили выше — они всего лишь продолжают написанное, генерируя по токену за раз. Во время процедуры предобучения такие модели видят миллионы текстов, и на основе них учатся определять вероятности появления того или иного слова в контексте. Если же модели вместо обычного человеческого языка показывать, скажем, код на разных языках программирования — для нее задача не изменится. Это все еще предсказание следующего токена — названия переменной, метода, атрибута или класса. На этом принципе основана другая GPT-like модель Codex. Обучение новому языку или новым типам задач (перевод, сокращение текста — суммаризация, выявление логических связей) — всё это достижимо при дообучении модели, если подобранны правильные данные и они «скармливаются» модели в понятном формате (с изображениями такая модель работать не будет — просто не ясно, как их перевести в текст).

Базовый принцип обучения WebGPT с учителем

А что такое правильные данные в контексте поиска информации в интернете? Это поисковые сессии реальных пользователей, или демонстрации. Важно разработать метод, как последовательность действий будет представляться модели (причем, языковой модели — то есть хочется еще и переиспользовать ее знания об естественном языке), чтобы получился «понятный» формат. Следует начать со списка действий, которые доступны человеку (и модели):

  1. Отправить поисковый запрос в API/строку поиска (авторы используют Bing, и вообще коллаборация OpenAI — Microsoft всё масштабнее и масштабнее) и получить ответ;

  2. Кликнуть на ссылку в выдаче;

  3. Найти текст на стрице;

  4. Прокрутить страницу вверх или вниз;

  5. Вернуться на страницу назад.

Это действия связанны с «браузером», но так как мы решаем задачу генерации ответа на вопрос (именно генерации, а не просто поиска — ведь сам поисковый движок Bing выдаст ответ, но он может быть неполным, неточным), то логично добавить еще два шага: это «цитировать/выписать» (то есть запомнить найденных текст со страницы для себя на будущее) и «сформулировать ответ» — чтобы мы могли понять, что модель закончила работу, и последний написанный текст стоит воспринимать как ответ. Опционально можно ограничивать количество действий, предпринимаемых моделью, что на самом деле важно, ведь для получения очередной команды от модели необходимо ждать существенное количество времени (большие модели размерами в несколько десятков миллиардов параметров тратят на генерацию ответа 0.3-20 секунд, в зависимости от длины текста, размера модели и используемых GPU/TPU). Ожидание ответа на вопрос больше минуты явно не способствует улучшению пользовательского опыта.

Команда OpenAI предлагет оригинальное решение перевода пользовательских демонстраций в виртуальный «браузер» для модели, который полностью представлен текстом:

См. обозначения для текста ниже
См. обозначения для текста ниже

И соответствующий этому cостоянию UI, который видел бы пользователь условного браузера (side-by-side для удобства соотнесения элементов):

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

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

  1. Основной вопрос, который задан модели. Он не меняется в течение всей работы над одним ответом;

  2. Блок цитат, которые модель сама себе выписывает. Она сама определяет, с какой части текста по какую цитировать источник. В целом можно сказать, что из этого блока знаний модель и будет генерировать финальный ответ, опираясь на информацию, «отложенную» на будущее в этом блоке. На каждом этапе работы модели видны все цитаты, и LM может понимать, какую информацию сверх этого нужно найти для полного ответа на вопрос, что позволяет писать и отправлять новые запросы в Bing;

  3. Блок последних выполненных в браузере действий, добавленный для консистентности, чтобы модель не повторялась, и не заходила в петлю одних и тех же команд. Важно понимать, что между двумя соседними «прогонами» текста через LM информация никак не сохраняется, и её веса не меняются. Можно сказать, что у модели нет памяти, и именно этот блок помогает отслеживать траекторию ответа на вопрос, чтобы не запутаться;

  4. Заголовок текущей страницы. Тут будет отражен реальный заголовок, если модель «кликнула» на какую-либо ссылку;

  5. Блок текущего окна браузера. Здесь представлено то, что видел бы человек в UI. В конкретном случае предудущее действие — это запрос в API («how to train crows to bring you gifts», как видно из блока 3), а значит в блоке 5 представлена часть поисковой выдачи (для примера — 2 ссылки, и их краткие описания). Сейчас модель видит строчки 0-11, и, если будет сгенерирована соответствующая команда, страница прокрутится, и станут доступны новые поисковые результаты;

  6. Вторая ссылка из выдачи поисковика, по сути то же самое, что и блок 5;

  7. Счетчик оставшихся действий (каждый раз уменьшается на единицу) и запрос следующей команды от модели (Next Action), которая должна быть сгенерирована.

Всё это описано текстом, и подается в текстовую модель как контекст в надежде на то, что в ответ LM сгенериурет следующую команду (вроде «кликни на ссылку один» или «промотай страницу вниз»). Такой контекст называется prompt (промпт). Чем он «качественнее», чем ближе он к тому, что понимают модели (что они видели во время тренировки), тем лучше модель генерирует ответы.

Сверху указан текстовый промпт, подающийся в модель. Он содержит 2 примера перевода текстовой задачи в код React-компонентов. Затем идёт третий запрос, а код предлагается сгенерировать самой модели. Она понимает, что требуется - потому что есть пара наглядных примеров - и начинает дописывать осмысленный ответ.
Сверху указан текстовый промпт, подающийся в модель. Он содержит 2 примера перевода текстовой задачи в код React-компонентов. Затем идёт третий запрос, а код предлагается сгенерировать самой модели. Она понимает, что требуется — потому что есть пара наглядных примеров — и начинает дописывать осмысленный ответ.
Интересный факт про промпты

Вообще работа над промптами — вещь очень важная. Вы могли об этом слышать или даже заметить самостоятельно, если пытались сгенерировать что-то в MidJourney / DALL-E 2 / Stable Diffusion. Простой запрос на генерацию изображения может вас не удовлетворить, но если добавить теги «screenshot in a typical pixar movie, disney infinity 3 star wars style, volumetric lighting, subsurface scattering, photorealistic, octane render, medium shot, studio ghibli, pixar and disney animation, sharp, rendered in unreal engine 5, anime key art by greg rutkowski and josh black, bloom, dramatic lighting» — то результат может приятно удивить 🙂

Еще важнее роль промптов при генерации текста языковыми моделями. Мой любимый пример — это добавление фразы «Let’s think step by step» в конец запроса с задачей на несколько действий (было представлено в этой статье).

Слева - запрос на решение задачи, для которой модель генерирует неправильный ответ "8". Справа - добавление волшебной фразы, заставляющей модель объяснить свой ответ шаг за шагом, что, в свою очередь, позволяет LLM сгенерировать правильный ответ "4".
Слева — запрос на решение задачи, для которой модель генерирует неправильный ответ «8». Справа — добавление волшебной фразы, заставляющей модель объяснить свой ответ шаг за шагом, что, в свою очередь, позволяет LLM сгенерировать правильный ответ «4».

Данная фраза «включает» режим CoT, что означает «chain-of-thought», или цепочка рассуждений/мыслей. Включает не в прямом смысле — скорее просто заставляет модель следовать этой инструкции, и писать выкладки одну за другой. Интересно, что такой эффект значимо проявляется только у больших языковых моделей (Large Language Models, LLMs) — обратите внимание на ось OX, где указаны размеры моделей (в миллиардах параметров):

По оси OY указаны метрики на некоторых датасетах. Видно, как добавление всего лишь одной фразы магическим образом существенно увеличивает качество — но только при соответствующих размерах.

Описание (ссылка на телеграм) еще одного примера промптинга для выполнения сложных задач.

На мой взгляд, важны тут две вещи: то, что модель сама формулирует запросы в браузер, и то, что она умеет выписывать ответы во «внешнюю память» (на листочек 🙂 ). Именно с помощью этих двух механизмов и удается на основе цитат сформулировать полный ответ, подкрепленный фактами и источниками.

Итак, человеческие демонстрации собраны, поисковые сессии переведены в текстовую информацию, и теперь можно дообучить уже существующую языковую модель в классическом режиме предсказания следующего слова, чтобы она скопировала поведение реальных людей при поиске ответов. На этапе тренировки модель каждый раз видит, какой Next Action был выполнен человеком, и учится по промпту (текущему состоянию, с цитатами и поисковой выдачей) это следующее действие угадывать. На этапе предсказания же, как было показано на скриншотах выше (блок 7) промпт в конце содержит фразу «Next Action», а модель в режиме генерации текста уже сама отдает команду. Всего для обучения использовалось 6,209 демонстраций (из интересного — публично доступна инструкция для краудсорсеров; оцените полноту описания задачи и действий. Из своего опыта знаю, что собрать данные от разных людей с разными мнениями бывает очень тяжело, данные друг другу противоречат, и тем важнее максимально подробно донести до исполнителей, что от них требуется). Полученную модель назовем BC-моделью, где BC означает Behavioral Cloning (клонирование поведения), потому что она училась повторять за людьми.

Готова ли наша модель?

Шаг обучения WebGPT для продвинутых: готовим данные

На самом деле нет 🙂 эти демонстрации лишь показали модели, как взаимодействовать с браузером, что от модели ожидается в качестве команд к действию (Next Action), и как в общем генерировать запросы в Bing API. Финальная цель — сделать модель, которая оптимизрована под качество ответов (измеренное людским мнением), включая, но не ограничиваясь, правдивостью ответа. Тренировка на демонстрациях же не оптимизирует эту метрику каким либо образом. Обратите внимание, это в целом очень частая проблема в машинном обучении — модели обучаются на какую-то прокси-функцию, которая, как мы верим, сильно скоррелированна с метрикой реального мира. Скажем, можно минимизировать квадрат ошибки предсказания продаж в магазине на следующей неделе, но ведь реальная метрика — это деньги, заработанные или полученные компанией. Не всегда удается достигнуть высокой корреляции между этими двумя вещами. Как же обучить модель напрямую оптимизировать предпочтения реальных людей?

В самом слове «предпочтение» есть что-то, что наталкивают на идею сравнений. Оценить какой-то объект в вакууме (абстрактной цифрой от 1 до 10, например, как это часто бывает с фильмами или играми) куда сложнее, чем отранжировать его относительно другого схожего объекта. Само определение подсказывает: «Предпочтение — преимущественное внимание, одобрение, уважение к одному из нескольких вариантов, желание выбрать один из нескольких вариантов«. Тогда, чтобы обучить модель производить ответы, которые наиболее предпочтительны с точки зрения людей, необходимо создать набор пар для сравнения. В контексте ответов на вопросы с помощью поисковой системы это означает, что на один и тот же вопрос предлагается два разных ответа (возможно даже с разным выводом из этих ответов), разные наборы источников, из которых этот ответ собран/сгенерирован.

Такие пары для сравнения (имея обученную на демонстрациях модель) получать очень легко — LMки это алгоритмы вероятностные, как было упомянуто ранее, поэтому можно семплировать действия при генерации команд или ответе на вопрос. Простой пример: модель после получения запроса предсказывает команду «кликни на ссылку 1» с вероятностью 40%, и команду «промотай вниз, к следующему набору ссылок» с вероятностью 37%. Уже на этом этапе доступна развилка в дальнейшей логике поиска информации, и можно запустить эти два процесса в параллель. Таким образом, через сколько-то действий каждая модель придет к ответу, но разными путями. Их мы и предложим сравнить человеку (финальные ответы и подкрепляющие их источники, не пути).

Интерфейс для сравнения двух ответов (Option A и Option B сверху). Сначала предлагается оценить каждый ответ по отдельности по нескольким критериям Затем уже по ним сравниваются два ответа, и выносится финальный вердикт. Идеальная иллюстрация процесса декомпозиции сложной непонятной задачи в четко формализованную.
Интерфейс для сравнения двух ответов (Option A и Option B сверху). Сначала предлагается оценить каждый ответ по отдельности по нескольким критериям Затем уже по ним сравниваются два ответа, и выносится финальный вердикт. Идеальная иллюстрация процесса декомпозиции сложной непонятной задачи в четко формализованную.

При оценке каждого из двух ответов используются следующие критерии:

  1. Содержит ли ответ неподкрепленную источниками информацию?

  2. Предоставлен ли ответ на основной вопрос?

  3. Присутствует ли дополнительная полезная информация, которая не требуется для ответа на вопрос?

  4. Насколько ответ последователен, и есть ли в нем ошибки цитирования источников/самого себя?

  5. Сколько нерелевантной информации в тексте ответа?

По этим критериям ответы сравниваются, и человек выбирает из 5 обобщённых опций, которые используются в качестве разметки на следующем этапе обучения (А сильно лучше Б, А лучше Б, А и Б одинаковые, А хуже Б, А сильно хуже Б). Полная инструкция для исполнителей также доступна. Интересный факт: исполнители не обязаны делать проверку фактов, указанных в источниках, процитированных моделью. Получается, люди оценивают то, насколько хорошо модель умеет опираться на уже предоставленные факты (размещенные на страницах в интернете), без факт-чеккинга.

WebGPT не сёрфят

Как во время обучения, так и во время генерации ответов WebGPT имеет прямой доступ к сети Интернет — однако все заимодействия ограничены возможностью отправки запросов в единственное API. Это позволяет модели давать актуальные ответы на широкий круг вопросов, но потенциально создает риски как для пользователя (некорректные ответы), так и для других юзеров. Например, если бы у модели был доступ к веб-формам/веб-редакторам, она могла бы исправить данные в Википедии, чтобы создать надежную ссылку с указанием источника конкретного ложного факта. Даже если бы люди-демонстраторы не вели себя подобным образом во время сбора тренировочных данных, такое поведение, скорее всего, было бы подкреплено и закреплено во время обучения, если бы модель наткнулась на него случайно. Подробнее про эксплуатацию несовершества среды и фунцкции награды см. ниже.

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

Авторы подчеркивают, что это проблема для будущих исследований и статей. Я добавлю, что её абсолютно точно необходимо будет решить перед переносом аналога WebGPT в продакшен — например, добавить рейтинги доверия сайтам; указывать, что источник ненадежный; учиться фильтровать источники по агрегированной информации (4 сайта указывают дату, отличную от выбранного источника? тогда этот факт как ненадежный, и не используем в цитировании); наконец, оценка верности факта самой моделью: насколько вероятно, что обычная LM дала бы тот же ответ?

Заметка про надежность сайтов и фактов

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

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

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

Шаг обучения WebGPT для продвинутых: учим модель учить модель

В предшествующих исследованиях OpenAI было эмпирически выяснено, что модели в целом хорошо предсказывают реакции людей и их оценки в задачах, связанных с генерацией комплексных ответов. Вырисовывается следующая схема, которая является ключевой для обучения по обратной связи от людей (human feedback):

  1. Генерируем набор пар для сравнения, используя модель, обученную на демонстрациях (она уже умеет «серфить» интернет, писать запросы и «кликать» по ссылкам, то есть выдавать соответствующие команды в виде текста);

  2. Размечаем пары с использованием людей;

  3. Тренируем другую модель предсказывать разметку людей (какой ответ из пары получит более высокий ответ) на парах из п.2. Назовем такую модель Reward Model (RM). Она принимает на вход вопрос и финальный сгенерированный ответ (без промежуточных шагов вроде прокрутки браузера), а выдаёт одно вещественное число (оно еще называется наградой, или Reward — по историческим причинам). Чем больше это число — тем выше вероятность того, что человек высоко оценит этот ответ по сравнению с остальными. Можно считать, что это условный ELO-рейтинг, как в шахматах;

  4. Обучаем основную модель (BC) на основе оценок от модели из п. 3; По сути LM учится решать задачу «как мне поменять свой сгенерированный ответ так, чтобы получить большую оценку RM?«;

  5. Повторяем пункты 1-4 итеративно.

Step 1 слева: описанное выше дообучение модели на демонстрациях; Step 2 в центре: собираем ответы текущей модели (п.1 в плане), размечаем (п.2), тренируем RM (п.3) Step 3 справа: на новых данных производим оценку новых пар сгенерированных ответов, дообучаем WebGPT (п.4)
Step 1 слева: описанное выше дообучение модели на демонстрациях; Step 2 в центре: собираем ответы текущей модели (п.1 в плане), размечаем (п.2), тренируем RM (п.3) Step 3 справа: на новых данных производим оценку новых пар сгенерированных ответов, дообучаем WebGPT (п.4)

Этот пайплайн имеет две ключевые особенности. Во-первых, его можно повторять итеративно, улучшая именно текущую модель, со всеми ее минусами и плюсами. Если LM в какой-то момент начала обманывать, или использовать несуществующие факты (дефект обучения) — это будет заметно на разметке людьми, и соответствующие ответы получат низкие оценки. В будущем модели будет невыгодно повторять подобное (возникнет negative feedback). А во-вторых, и это просто прекрасно — используя RM из пункта 3, мы можем сгенерировать оценки для куда большего количества пар (и гораздо быстрее), чем если бы это делали люди. Следите за руками: берем любые доступные вопросы из интернета, из датасетов или даже специально заготовленные, на которых модель еще не обучалась, генерируем ответы, оцениваем их автоматически, без привлечения людей, и уже на основе этих оценок дообучаем основную WebGPT. Если люди могут за, скажем 10,000$ разметить 5,000 пар за неделю, то 1 землекоп RM может за день отранжировать десятки и сотни тысяч пар ответов фактически за копейки.

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

В машинном обучении выделяют несколько «царств» (или скорее направлений) алгоритмов обучения. Детали меняются от одной классификации к другой, где-то происходит обобщение по конкретным критериям, но практически всегда и везде упоминается три основных подхода:

  1. Обучение с учителем (Supervised Learning) — когда есть размеченные данные, и нужно научиться на их основе обобщать знания на генеральную совокупность всех объектов. Сюда относятся модели для классификации, регрессии (предсказание числовых величин);

  2. Обучение без учителя (Unsupervised Learning) — когда разметки нет, но хочется каким-то образом извлечь знания из данных. Популярный пример — разнообразные кластеризации и выделение когорт;

  3. Обучение с подкреплением (Reinforcement Rearning, RL) — когда есть некоторые особенности получения данных, и их качество зависит от самого подхода. Именно методы из этой категории учатся играть в шахматы, в го и любые компьютерные игры (чтобы получить данные — надо играть, и чем выше уровень игры, тем лучше данные).

Википедия в новом дизайне поддакивает такой простой классификации на 3 категории.
Википедия в новом дизайне поддакивает такой простой классификации на 3 категории.

Как легко догадаться по описанию пайплана обучения WebGPT — нам подходит третий вариант. RL методы взаимодействуют со средой (или окружением, environment), посылают в нее выбранные действия, получают обновленное состояние (описание мира), и пытаются найти лучшую стратегию. Очень часто система получения награды, которую и старается максимизировать алгоритм, недоступна: для игры го нельзя сказать, является ли в моменте одна позиция выигрышнее другой (ведь партию можно доиграть по-разному); в игре Minecraft вообще почти не ясна связь деревянной кирки и добычи алмаза — по крайней мере до тех пор, пока сам игрок один раз не пройдет путь от начала и до конца. Поэтому в мире обучения с подкреплением используют моделирование награды, и это в точности то, для чего мы обучали Reward Model — предсказывать предпочтения человека. Таким образом снижается требование к количеству реальных взаимодействий со средой (людьми-разметчиками с почасовой оплатой) — ведь можно опираться на выученную из предоставленной разметки закономерность.

За долгие годы развития направления RL было придумано множество алгоритмов, с разными трюками и ухищрениями (чаще всего — под конкретные типы задач, без возможности обобщиться на любые произвольные цели). Иногда для успешного обучения нужно вручную конструировать принцип оценки действий модели — то есть вручную указывать, что, например, действие А в ситуации Б нанесет урон вашему персонажу, и тот получит меньшую награду. Все это плохо масштабируется, и потому ценятся стабильные методы, выступающие в роли швейцарского ножа. Они хорошо обобщаются, не требуют тончайшей настройки и просто работают «из коробки».

Один из таких методов — Proximal Policy Optimization, или PPO. Он был разработан командой OpenAI в 2017м году, и как раз соответствовал требованиям простого прикладного инструмента, решающего большой спектр задач. Мы не будем погружаться в детали его работы, так как по этой теме можно прочитать не то что отдельную лекцию — целый курс. Общий смысл алгоритма в том, что мы обучаем модель-критика, которая оценивает наш текущий результат, и мы стараемся взаимодействовать со средой лучше, чем в среднем предсказывает критик. Критик в оригинале очень похож на описанную раннее Reward Model.

Сам же алгоритм был протестирован командой OpenAI на разнообразных задачах, включая сложную компьютерную игру, требующую кооперации нескольких игроков (или моделей) и далёкий горизонт планирования — DotA 2. Полученная модель (с некоторыми игровыми ограничениями) выигрывала у чемпионов мира — более подробно об этом можно прочитать в официальном блоге (даже записи всех игр доступны!).

Как модель для DotA 2 видит поле боя - принцип сбора признаком для подачи в нейросеть.
Как модель для DotA 2 видит поле боя — принцип сбора признаком для подачи в нейросеть.

Формула стандартизации. X - конкретный пример значения RM для одного ответа, μ - среднее по всей выборке, σ - стандартное отклонение в предсказанных значениях на выборке.
Формула стандартизации. X — конкретный пример значения RM для одного ответа, μ — среднее по всей выборке, σ — стандартное отклонение в предсказанных значениях на выборке.

Важное замечение по Reward Model для графиков ниже по статье: часто по оси OY будет Reward Value (оно же RM Score). Для удобства сравнения, во всех случаях предсказания RM были стандартизированы, то есть из предсказанного значения вычитали среднее по всем генерациям (поэтому среднее значение теперь равно нулю; и больше нуля — значит лучше среднего), и полученную разность делили на стандартное отклонение (поэтому в большинстве случаев Reward находится в интервале [-1; 1]). Однако основная логика сохраняется — чем больше значение, тем лучше оценен ответ.

В такой постановке задачи оптимизации очень легко переобучить модель под конкретную Reward Model, а не под оценки разметчиков, под общую логику. Если это произойдет, то LM начнет эксплуатировать несовершества RM — а они обязательно будут, как минимум потому, что количество данных, на которых она тренируется, очень мало (суммарно на всех итерациях оценено порядка 21,500 пар, но для тренировки доступно 16,000), и её оценка не в точности повторяет оценки людей. Можно представить случай, что RM в среднем дает более высокую оценку ответам, в которых встречается какое-то конкретное слово. Тогда WebGPT, чрезмерно оптимизирующая оценку RM (вместо людской оценки, как прокси-метрику), начнет по поводу и без вставлять такое слово в свои ответы. Подобное поведение продемонстрировано в другой, более ранней статье OpenAI, с первыми попытками обучения моделей по обратной связи от людей:

Сверху указан контекст, к которому необходимо дописать продолжение. Две колонки представляют собой два разных варианта продолжения, сгенерированных переобученной моделью. Видно, что в выделенной строке слова These и easily повторяются несколько раз подряд.
Сверху указан контекст, к которому необходимо дописать продолжение. Две колонки представляют собой два разных варианта продолжения, сгенерированных переобученной моделью. Видно, что в выделенной строке слова These и easily повторяются несколько раз подряд.

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

Заметка про актуальность проблемы

Так считает и сама OpenAI — аккурат перед выходом ChatGPT была опубликована статья с глубоким анализом процесса излишней оптимизации под RM: Scaling Laws for Reward Model Overoptimization. В ней исследователи пытаются разобраться, как долго можно тренировать LM-модель относительно RM, без добавления новых данных от людей, чтобы не терять в качестве генерации, и в то же время максимально эффективно использовать существующую разметку. Интересно то, что эксперименты ставятся по отношению к другой, второй RM (Gold на графике ниже), которая выступает в роли «реальных людей» — и экспериментально показывается, что ее оценка начинает с какого-то момента падать, хотя по основной RM, на основе которой тренируется аналог WebGPT, виден рост. Это демонстрирует ровно описанный выше эффект овероптимизации, переобучения, когда оценки RM перестают соответствовать ощущению людей-разметчиков.

График из статьи, описывающий связь прокси-оценки сгенерированных ответов и "реальной" оценки.
График из статьи, описывающий связь прокси-оценки сгенерированных ответов и «реальной» оценки.

По оси OX — длительность обучения модели (измеренная в отклонении предсказаний от исходной модели, обученной на демонстрациях. Чем больше отклонение — тем дольше учится модель, при прочих равных). По оси OY — оценка RM. Пунктирные линии — оценки основной RM, сплошные — оценки «настоящей» RM, имитирующей оценки людей (не дообучается в процессе эксперимента). Обратите внимание, что ось OY начинается в нуле — потому что это среднее значение оценки Reward после стандартизации (формулу и процесс см. выше). Чем выше RM Score, тем больше модель «выигрывает» в оценке своих ответов относительно исходной модели.

Видно, что пунктирные линии показывают рост, так как мы оптимизируем их предсказания напрямую. В это же время оценки «настоящие», полученные как будто бы от людей, падают — при чём тем быстрее, чем меньше размер RM. Так, оптимизация против самой «толстой» модели на 3 миллиарда параметров не приводит к деградации — оценка выходит на плато. Второй интересный вывод — чем больше параметров в RM (чем светлее линия), тем выше средняя оценка модели, полученная обучением против такой RM. Это, конечно, не открытие — мол, бери модель потолще, и будет обучаться лучше — однако подтверждает тезис о том, что переобучения при тренировке RM на разметку людей не происходит (при правильном подходе и гиперпараметрах), а еще позволяет численно оценить эффект прироста в качестве генерации.

Курьёзные случаи эксплуатации неидеальности условий награды

С методами в RL есть одна проблема — они очень эффективны в эксплуатации уязвимостей среды. Они пойдут на любые меры, чтобы получить как можно большую награду (максимизируют Reward). Некоторыми подобными примерами мне захотелось поделиться с вами, для наглядности:

Предположим, у вас есть двуногий собаковидный робот, ограниченный вертикальной плоскостью, то есть он может бегать только вперед или назад. Цель – научиться бегать. В качестве награды выступает ускорение робота. Нейросеть должна управлять сокращением мышц, чтобы контролировать движение. Что может пойти не так?

Произошел «reward hacking», или взлом принципа начисления награды. Со стороны это действительно может выглядеть глупо. Но мы можем это сказать только потому, что мы можем видеть вид от третьего лица и иметь кучу заранее подготовленных знаний, которые говорят нам, что бегать на ногах лучше. RL-алгоритм этого не знает! Он видит текущее состояние, пробует разные действия и знает, что получает какое-то положительное вознаграждение за ускорение. Вот и все! Если вы думаете, что в реальной жизни такого не бывает, то…

Из-за ошибки в физике жук обучился ползать на спине - а ему так удобнее!
Из-за ошибки в физике жук обучился ползать на спине — а ему так удобнее!

Более простой пример, когда ожидания могут не совпадать с получаемым поведением. Пусть есть балка, закрепленная на вращающемся шарнире в двумерной плоскости. Модель может давать команды вращать балку по часовой стрелке или против. Всего два действия. Задача — держать балку в стабильном сбалансированном положении и выше нижней половины. Всё очень просто — ставим её идеально вертикально, и готово!

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

И последнее — блогпост OpenAI про модели для игры в прятки, где были найдены и выучены очень сложные паттерны действий. Сами по себе эти действия не являются «обманами» среды или функции награды (Reward), но служат ответами на изменившееся поведение оппонента, эксплуатируя его предсказуемость. Враг закрылся в углу стенами? Принесу лестницу и перелезу. Соперник несет лестницу? Превентивно отберу её. И так далее, и так далее… Видео с объяснением:

Интересный факт про RL-подход: для улучшения сходимости, а также уменьшения количества необходимых данных при общей процедуре обучения, авторы раз в несколько шагов добавляли 15 эпизодов генерации финального текстового ответа по уже набранным источникам информации. Это позволяет писать более связные и консистентные ответы, и наилучшим образом (с точки зрения Reward Model, то есть почти человеческой оценки) использовать источники и текст из них.

Регуляризация при обучении WebGPT

Витя пробует подобрать правильный терм регуляризации.
Витя пробует подобрать правильный терм регуляризации.

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

Так как мы переживаем, что модель начнет эксплуатировать неидеальность Reward Model, и это выльется в бессмысленные или некорректные генерации, то стоит задуматься над добавлением штрафа за, собственно, бессмыслицу. Но как её оценить? Существует ли инструмент, который позвоялет определить общую адекватность и связанность текста?

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

Так выглядит член регуляризации на основе KL-дивергенции. Это логарифм отношения вероятностей, порожденных двумя моделями. Здесь x - это входной запрос или текст (промпт), y - генерируемая моделью часть, RL/SFT - указание на тип модели (в числителе - новая, обучаемая модель, в знаменателе - зафиксированная и обученная на демонстрациях). Pi означает конкретную модель и её оценки вероятностей токенов y при промпте x.
Так выглядит член регуляризации на основе KL-дивергенции. Это логарифм отношения вероятностей, порожденных двумя моделями. Здесь x — это входной запрос или текст (промпт), y — генерируемая моделью часть, RL/SFT — указание на тип модели (в числителе — новая, обучаемая модель, в знаменателе — зафиксированная и обученная на демонстрациях). Pi означает конкретную модель и её оценки вероятностей токенов y при промпте x.

Чаще всего для этой цели используется Дивергенция Кульбака-Лейблера: это нессиметричная неотрицательная мера удаленности двух вероятностных распределений. Чем более похожи распределения, тем меньше её значение, и наоборот. Это значение вычитается из общей награды, и — так как мы решаем задчачу максимизации — мешает достижению цели. Таким образом, мы вынуждаем модель найти баланс между отступлением от исходной BC с точки зрения генерируемых вероятностей для текста и общей наградой за генерацию. Приведённый подход — не панацея, и он не позволит бесконечно тренировать модель относительно зафиксированной RM, однако может продлить процесс, увеличивая тем самым эффективность использования разметки.

Альтернатива RL: меняем шило на мыло

Обучение с применением RL — задача не из лёгких, тем более на такой необычной проблеме, как «оптимизация генерируемого текста согласно фидбеку людей«. Пользуясь тем, что WebGPT представляет собой языковую модель, оперирующую вероятностями, из которых можно семплить, авторы предлагают альтернативный способ, который не требует дообучения модели (относительно BC, после использования датасета демонстраций), однако потребляет куда больше вычислительных ресурсов.

Этот метод называется Best-of-N, или Rejection Sampling, и он до смешного прост. После полученя первой группы размеченных пар сравнений ответов WebGPT, согласно плану пайплана, обучается Reward Model. Эта модель может выступать в качестве ранжировщика для десятка (или N, если быть точным. Best-of-64 означает ранжирование 64 вариантов) потенциальных ответов одновременно, ее задача — проставление оценки (согласно предсказанию) и упорядочивание всех ответов. Самый высокооценённый ответ из всех и является финальным.

Разные ответы получаются за счет разных действий, сгенерированных WebGPT — на самом раннем этапе это может быть слегка изменённая формулировка вопроса в Bing API; чуть позже — прокрутка на 3-4 страницу поисковой выдачи вместо проверки топа; под конец — финальные формулировки, используемые для связывания процитированных фактов. Развилок достаточно много (во время генерации каждой команды! А ведь их может быть и 100), и потому варианты получаются действительно неоднородными. Более того, у модели появляется шанс «прокликать» как можно больше ссылок (в разных сессиях, но при ответе на один и тот же вопрос — то есть паралелльно). Быть может, лучший ответ на поступивший запрос спрятан в сайте с невзрачным описанием, которое видит модель в поисковой выдаче, однако внутри предоставлен наиболее точный ответ — в таком случае обилие посещённых сайтов играет лишь на руку. А главное — никакого обучения, как только получена версия Reward Model. Для генерации используется LM, обученная только на демонстрациях (BC, порядка 6,200 примеров — очень мало по меркам Deep Learning /современного NLP).

График затрачиваемых вычислительных ресурсов против получаемой оценки. На основе замеров по трём моделям разных размеров произведена оценка оптимального количества N генерируемых ответов.
График затрачиваемых вычислительных ресурсов против получаемой оценки. На основе замеров по трём моделям разных размеров произведена оценка оптимального количества N генерируемых ответов.

А сколько разнообразных ответов оптимально генерировать для ранжирования, и что вообще такое «оптимально«? Ответы на эти вопросы представлены на картинке слева. Чем больше модель, тем больше генераций можно пробовать ранжировать, и тем больший прирост к метрике это даст. В целом, это логично — большие модели хранят больше знаний, их выдача более разнообразна, а значит может привести к таким сайтам и, как следствие, ответам, которые не встречаются у других моделей. Оптимальными считаются точки перегиба на графике, где прирост метрики за счет наращивания ресурсов начинает уменьшаться. Это значит, что можно взять модель чуть-чуть побольше, натренировать ее и получить метрику немного выше. Однако видно, что даже маленькая модель на 760M параметров может тягаться с 175B гигантом — просто нужно генерировать порядка сотни вариантов (и это всё еще будет на порядок вычислительно эффективнее 2-3 вариантов от LLM GPT-3). Отмеченные на графике звёздочками точки являются оптимальными для рассматриваемых моделей, и именно эти значения будут использовать для рассчета метрик ниже (например, N=16 для средней модели на 13B параметров).

Метрики и восприятие людьми

Начнем с конца — попробуем оценить, какой из методов генерации ответов показывает себя лучше: RL (обучение через моделирование функции оценки ответа) или BoN (без дообучения; множественное семплирование из модели). Может ли их комбинация прирастить качество генерируемых ответов еще сущестеннее?

Попробуем разобраться, как производить такое сравнение. У нас есть модель, обученная исключительно на 6,200 демонстрациях, без прочих трюков, и в режиме языкового моделирования. Напомню, что её называют BC (Behavioral Cloning). Относительно ответов, порождаемых этой моделью, можно проводить сравнения по уже описанному выше принципу с ответами от других моделей. Если качество ответов в среднем одинаковое, то можно ожидать ситуации 50/50 — когда в половине случаев люди предпочтут ответ первой модели, а в половине — второй. Если ответы одной модели стабильно выигрывают в 55% случаев — можно сказать, что — согласно оценке людей — её ответы качественнее.

Предпочтение RL модели над 175B BC (обученной только на  демонстрациях) с использованием или без использования BoN-семплинга (справа и слева соответственно). Маленькие чёрточки сверху представляют +-1 стандартное отклонение при измерении метрики (доверительный интервал).
Предпочтение RL модели над 175B BC (обученной только на демонстрациях) с использованием или без использования BoN-семплинга (справа и слева соответственно). Маленькие чёрточки сверху представляют +-1 стандартное отклонение при измерении метрики (доверительный интервал).

Именно поэтому величина в 50% отмечена пунктирной линией на графике — это наша отправная точка, и мы хотим видеть прирост доли выигранных сравнений относительно заданного уровня. Из графика можно сделать несколько выводов. Во-первых, RL позволяет улучшить модель, натренированную на демонстрациях (то есть все эти трюки с RM и разметкой были не зря!). Во-вторых, самый лучший результат — 58% побед для 175B Bo1 модели. В-третьих, RL и Rejection Sampling плохо сочетаются, и либо ухудшают результат, либо не меняют его существенно (исключение 13B-Bo16 модель, однако это скорее выброс, случившийся из-за маленького размера выборки для оценки).

Предпочтение 175B-BoN модели относительно 175B BC. Черная пунктирная линия характеризует вероятность победы сгенерированного ответа при оценке людьми. Для голубой линии закрашенная площадь характеризует +-1 стандартное отклонение.
Предпочтение 175B-BoN модели относительно 175B BC. Черная пунктирная линия характеризует вероятность победы сгенерированного ответа при оценке людьми. Для голубой линии закрашенная площадь характеризует +-1 стандартное отклонение.

Если же сравнить отдельно BoN модель (генерация N ответов BC-моделью и ранжирование через оценку RM) с самой BC моделью (то есть параметры сетей одинаковые, отличается только способ получения ответа, и как следствие вычислительная мощность, необходимая для генерации), то процент побед будет равняться 68% (при N=64, что, согласно приведенной оценке выше в статье, является оптимальным значением). Получается, что одной и той же BC модели Bo64 проигрывает в 32% случаев, а RL — в 42%. Разница существенна, если учесть, что метрика рассчитана на реальных человеческих оценках, восприятии. По этой причине дальше авторы статьи большинство экспериментов делают именно с BoN-моделями, а не RL. Но вообще интересно разобраться, почему так может происходить, что дообученная модель хуже показывает себя, чем модель, видевшая лишь 6,200 демонстраций. Можно выдвинуть несколько гипотез или связать это со следующими фактами:

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

  2. Среда, в которую «играет» наша модель (интернет и вебсайты, поисковый движок), безумно сложна для прогнозирования. В то же время с применением Rejection Sampling модель может попытаться посетить гораздо больше веб-сайтов, и затем оценить полученную информацию через RM;

  3. RM была натренирована в основном на сравнениях, сгенерированных BC и BoN-моделями, что ведет к смещению в данных. Быть может, если собирать датасет сравнений исключительно под PPO-алгоритм, то проигравший и победитель поменяются местами;

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

  5. Вполне возможно, что в результате неоптимального выбора параметров в пункте 4 произошло переобучение под RM, и модель потеряла обобщающую способность. Как следствие — получает более низкие оценки ответов от людей;

Стоит дополнительно отметить, что немало усилий было приложено и к обучению исходной BC модели. Авторы долго и тщательно подбирали гиперпараметры, и в итоге это привело к существенному сокращению разрыва в метриках, который изначально наблюдался между BC и RL подходами. Таким образом, сам по себе бейзлайн в виде BC достаточно сильный, производящий осмысленные и высокооцененные ответы.

Следующим логичным шагом становится сравнение лучшей модели (175B Bo64) с ответами, написанными самими живыми людьми. Это не упоминалось ранее, однако исходные вопросы для сбора демонстраций и генерации пар на сравнение (в RL/RM частях) были выбраны из датасета ELI5. Он сформирован следующим образом: на Reddit есть сабреддит Explian me Like I’m Five (ELI5), где люди задают вопросы, и в комментариях получают ответы. Для сбора демонстраций при тренировке BC разметчики сами искали ответы на вопрос, прикрепляли источники информации/ссылки (как было описано далеко в начале статьи). Однако в самом датасете ответами считаются самые высокооцененные (залайканные) комментарии, с некоторыми фильтрациями и ограничениями. И формат таких ответов существенно отличается от производимого моделью: там (зачастую) нет ссылок-источников, упоминаемые факты не сопровождаются аннотацией ([1][2] для указания на первый и второй источник, к примеру).

Пример данных с сабреддита ELI5. В заголовке содержится вопрос, снизу - комментарий, собравший оромное количество голосов "за". Значит, люди удовлетворены таким ответом.
Пример данных с сабреддита ELI5. В заголовке содержится вопрос, снизу — комментарий, собравший оромное количество голосов «за». Значит, люди удовлетворены таким ответом.

Указанные особенности подводят нас к развилке:

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

  2. С другой, если на этапе постобработки вырезать блок ссылок из ответа модели, а также их упоминания-референсы в тексте, то такие ответы, в теории, можно сравнить с исходными комментариями людей на Reddit.

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

Результаты человеческой оценки ответов модели против сгенерированных. Слева - метрики для случая [1], с указанием источников и ссылок, справа - метрики предпочтений против оригинальных ответов с Reddit, написанных добрыми и готовыми помочь людьми.
Результаты человеческой оценки ответов модели против сгенерированных. Слева — метрики для случая [1], с указанием источников и ссылок, справа — метрики предпочтений против оригинальных ответов с Reddit, написанных добрыми и готовыми помочь людьми.

Оценивалось всего три показателя — общая полезность ответа, согласованность и фактическая точность. На графике слева видно, что большая модель 175B Bo64 генерирует ответы, которые в 56% случаев признаны более полезными, чем ответы, полученные ручным поиском живого человека с последующей ручной компиляцией ответа по источникам. Немного страдает согласованность, а фактическая аккуратность держится на уровне. Можно сказать, что таким сгенерированным ответам стоит доверять, как если бы вы сами искали ответ на вопрос в интернете (не то что ответы ChatGPT или Galactica!). Главный вывод тут — модель выигрывает у написанных людьми ответов в более чем 50% случаев — то есть достигает уровня человека в использовании браузера для поиска информации. Также стоит отметить, что использование обратной связи от людей (пары сравнений для обучения Reward Model) имеет важнейшее значение, поскольку нельзя ожидать превышения планки 50% предпочтений только за счет подражания исходным демонстрациям (в лучшем случае мы научимся делать точно так же, и получится 50/50).

На графике справа, иллюстрирующем сравнение относительно оригинальных ответов из комментариев на Reddit, метрики еще лучше (ответ модели выбирается лучшим из пары 69% случаев). В целом, это не удивительно — люди пишут ответы в свободное время, ничего за это не получая (кроме апвоутов и кармы), и иногда ссылаются на знания из памяти, и не проверяют факты в интернете.


Заключение

Да, полученная модель не гарантирует выверенных и 100% фактологически точных ответов на запросы, однако это гораздо сильнее приближает описанный подход (и ChatGPT вместе с ним) к надежным поисковым системам, которые можно не перепроверять на каждом шагу. Более того, такие модели уже сейчас способны сами добровольно предоставлять источники информации, на которые опираются — а там дело за вами. Для самых терпиливых читателей, добравшихся до заключения, у меня подароктри сайта, в которых реализованы поисковики на принципах обучения моделей, описываемые в статье:

  1. https://phind.com/

  2. https://you.com/

  3. https://www.perplexity.ai/

Пример поисковой выдачи для запроса, ответа на который не существовало до середины декабря 2022. Скорее всего, этой информации не было в интернете на момент тренировки модели - однако ответ точен! UI: Справа ссылки как будто из Google, слева - ответ, сгенерированных на основе текста из них. Для ответов указан уровень уверенности, а для каждого предложения при наведении доступен источник - просто фантастика! Такие поисковые результаты это нам надо обязательно.
Пример поисковой выдачи для запроса, ответа на который не существовало до середины декабря 2022. Скорее всего, этой информации не было в интернете на момент тренировки модели — однако ответ точен! UI: Справа ссылки как будто из Google, слева — ответ, сгенерированных на основе текста из них. Для ответов указан уровень уверенности, а для каждого предложения при наведении доступен источник — просто фантастика! Такие поисковые результаты это нам надо обязательно.

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

P.S.: разумеется, от метода, разобранного в статье, до готового к внедрению в продакшен решения необходимо преодолеть огромное количество других проблем и инженерных задач. Я выбрал данную тему исходя из ситуации, которую наблюдаю в разнообразных телеграм, слак и прочих чатах: люди массово жалуются и упрекают ChatGPT в том, что она врет, подтасовывает факты. «Как это внедрять в поиск? Оно же даже дату развала СССР не знает!!!». В этом массовому потребителю и видится основная проблема. Надеюсь, что сейчас стало более понятно, как близки мы к новой парадигме обращения с поисковыми системами.

Новый UX Гугла радует...по крайней мере недовольных я не видел. Живыми.
Новый UX Гугла радует…по крайней мере недовольных я не видел. Живыми.

Об авторе

Статья подготовлена и написана Котенковым Игорем (@stalkermustang). Буду рад ответить на вопросы из комментариев и добавить обучающие заметки в текст материала по запросу.

Подписывайтесь на авторский телеграм-канал, где вас ждёт ещё больше новостей, разборов и объяснений из мира NLP, ML и не только! Кроме того, в чате канала можно обсудить идеи из статьи с другими участниками сообщества.


ссылка на оригинал статьи https://habr.com/ru/company/ods/blog/709222/

Как собрать самодельный принтер/плоттер

Картинка youtube-канал «stefanopadoan art»

Есть один весьма примечательный вид ЧПУ-устройств, который не оставит равнодушным никого — самодельный принтер.

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

И именно об интересных путях создания подобного устройства мы и поговорим в этой статье.

Любой принтер состоит из ряда компонентов, которые имеет смысл рассмотреть отдельно.

Двигатель

▍ Шаговый двигатель

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

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

Шаговые двигатели могут быть биполярными или униполярными.

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

Подобными двигателями управляют с применением мостового или полумостового драйвера.

В общей сложности подобные двигатели имеет две обмотки и четыре выходных контакта для управления (вариант «а» на рисунке ниже):

Картинка www.electroprivod.ru

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

Для упрощения конструкции иногда в подобных двигателях она выполняется таким образом, что серединные обмотки объединяются внутри двигателя (вариант «б» на рисунке ниже):

Картинка www.electroprivod.ru

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

Также подобного типа двигатель иногда может быть изготовлен таким образом, что все четыре обмотки выполняются отдельными — в таком случае двигатель будет содержать восемь выводов (вариант «в» на рисунке ниже):

Картинка www.electroprivod.ru

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

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

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

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

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

▍ Сервопривод

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

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

Таким образом, можно сказать, что сервопривод:

  • обеспечивает точное позиционирование вала двигателя;
  • оптимизирует работу электродвигателя, давая ему столько питания, сколько ему необходимо для выполнения конкретной работы. Благодаря чему увеличивается ресурс механических частей конструкции и экономится затрачиваемая энергия. Из-за этого КПД современных сервоприводов весьма высок (более 90%).

В общем случае преимуществами сервоприводов можно назвать следующие:

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

В то же время нельзя сказать, что шаговые двигатели однозначно проигрывают сервоприводам. Так как у них тоже есть свои преимущества:

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

Рамки статьи не позволяют в полной мере рассказать обо всех моментах, касающихся двигателей, однако наиболее интересные из них были подсвечены. Желающие могут углубиться в эту тему ещё больше.

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

▍ Драйвер двигателя

Для управления двигателем требуется специальная электронная плата, именуемая «драйвером».

Некоторые любители используют в своих конструкциях самодельные драйверы двигателя, однако для уменьшения трудозатрат автор статьи видит наиболее удобным использование покупного драйвера, подобрав его по поддерживаемому рабочему напряжению и максимальному току (взяв драйвер не впритык, а с некоторым запасом, например, в 30% по максимальному току).

Оптимальное напряжение для питания шагового двигателя (если оно не указано производителем) зависит от его индуктивности, значение которой можно взять из документации на двигатель:

$32\,\sqrt{{Индуктивность, в\,мГн}} = напряжение\,питания, В$

Наиболее широко распространёнными драйверами двигателей, которые используются в DIY-проектах, которые приходилось видеть автору, являются следующие:

L9110 L9110S / HG7881CP

Поддерживает:

  • максимальное напряжение на канал — в диапазоне от 2.5 до 12 В,
  • максимальный рабочий ток — 0.8 A.

L293D

Поддерживает:

  • максимальное напряжение на канал — до 25 В,
  • максимальный рабочий ток — 0.6 A.

Картинка www.amperkot.ru

L298N

Поддерживает:

  • максимальное напряжение на канал — в диапазоне от 5 до 35 В,
  • максимальный рабочий ток — 2 А.

Возможно использовать и любые иные, однако приходилось видеть эти наиболее часто в использовании (здесь специально не упомянуты драйверы «с ножками», которые, например, вставляются в платы FDM 3D-принтеров, а приведены исключительно драйверы с разъёмами, к которым можно что-то подключить).

Контроллер

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

Способы кодирования для печати

▍ G-код

Наиболее часто встречающимся способом (среди самодельных конструкций) кодирования информации для передачи её на исполнение устройству является её преобразование в так называемый G-код (весьма известная процедура для владельцев 3D-принтеров, которую там производит программа-слайсер).

Сразу стоит оговориться, что выделение способа управления через G-код в отдельную категорию принтеров весьма условно, т. к. теоретически все нижеприведённые принтеры могут его использовать (хотя для «попиксельного» способа печати, рассмотренного ниже, это не очень рационально, а для Polarograph, также рассмотренного ниже, не удалось выяснить этот момент).

G-код представляет собой особый язык программирования, появившийся ещё в начале 1960-х годов. Это последовательность команд, в которых содержатся инструкции машине на перемещение инструмента(ов) по определённым координатам, а также осуществление определённых операций с ним(и):

Картинка www.wikipedia.org

Более подробно об этом способе кодирования вы можете прочитать вот здесь.

А вот тут вы можете для интереса посмотреть список кодов, которые использует для своей работы известная прошивка 3D-принтеров Marlin.

Поэтому наиболее типичным способом использования G-кода в любительских конструкциях принтеров является следующий алгоритм:

  • выбор требуемого изображения/ надписи/узора;
  • преобразование его в G-код с использованием специального программного обеспечения;
  • загрузка G-кода в микроконтроллер;
  • выполнение задания микроконтроллером.

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

Как можно видеть, аппарат представляет собой всего лишь два шаговых двигателя с винтовыми приводами, которые отклоняют печатную головку по XY, которая представляет собой комплекс из письменной ручки и отклоняющего её сервопривода (служит для подъёма ручки, когда печать на данном участке не требуется).

Вкратце алгоритм работы с собранным устройством выглядит следующим образом:

  • скачать и установить open-source графический редактор Inkscape;
  • скачать и установить модуль для генерации G-кода из среды Inkscape;
  • загрузить какую-либо картинку в Inkscape;
  • экспортировать её в G-код;
  • загрузить и установить среду разработки Processing;
  • скачать написанный автором простой GUI под среду разработки Processing и запустить его изнутри этой среды;
  • загрузить с помощью GUI из предыдущего этапа G-код на микроконтроллер;
  • исполнить код с помощью микроконтроллера.

С примерно аналогичным принципом функционирования существует великое множество проектов, просто рассмотренный выше привлёк автора своей простотой.

«Попиксельное» кодирование

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

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

Картинка www.instructables.com

Автор принтера не стал отрисовывать собственные шрифты, вместо этого он воспользовался онлайн-генератором, в котором можно выбрать один из нескольких пиксельных шрифтов, после чего скачать его в виде кода ассемблерного типа.

Кстати сказать, если вы захотите построить подобное устройство, вы можете на странице проекта, которая была приведена выше, посмотреть исходный код устройства и, в частности, как подобный код шрифта загружается в скетч Arduino (устройство было построено именно на базе этого микроконтроллера). Шрифт хранится на SD-карте, с которой эта версия платы Arduino и читает информацию в процессе работы (ЗЫ: русского языка вроде как нет).

С технической точки зрения устройство достаточно несовершенное и не содержит даже приведения в соответствие скоростей двух колёс с отдельными двигателями в них (что, естественно, приводит к необходимости постоянного подруливания оператором, так как аппарат постоянно заносит «то туда, то сюда»). Кроме того, никаким образом не учитывается скорость движения аппарата (прямо просится доработка).

Тем не менее, работа аппарата выглядит достаточно впечатляюще. Сам автор описывает интересный эксперимент, который он проводил с этим устройством: заливал в него не просто воду, а воду с моющим средством, что приводило к повышенному очищению дороги на этих местах и надписи читались несколько месяцев!

В дальнейшем идея этого аппарата была развита ещё дальше установкой подобного устройства на велосипед:

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

Хотя если иметь в виду попиксельный способ нанесения (если его так можно назвать, хотя автор и понимает, что, наверное, это не совсем корректное название), то сюда же можно отнести и термотрансферные принтеры и прочее, прочее, прочее.

Печать каждого пикселя с учётом его яркости

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

Когда автор статьи его только увидел, он сразу неуловимо стал напоминать ему что-то… И автор вспомнил, что аналогичный проект ему уже доводилось видеть в начале двухтысячных годов, и назывался он Hektor. Как позже выяснилось, разработчик Polargraph тоже вдохновлялся именно этим устройством 🙂

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

В отличие от первых попыток, которые делал Hektor, Polargraph уже является более совершенным устройством:

Что позволяет ему создавать достаточно сложные изображения, которые можно найти в его онлайн-альбоме на Flickr:

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

А также выкладывают подробное описание по сборке аналогичного устройства.

Кстати сказать, если кому интересно, приведённый в «шапке» статьи коллаж составлен из работ, выполненных на аналогичного типа принтере. Сам автор не раскрывает точное устройство, отделываясь фразами «в интернете много аналогичных мануалов». Но делится способом подготовки файла, который даёт такой же результат, как в начале статьи. Рекомендует гуглить по ключевым словам «TSP art» и «алгоритм voronoi-stippling» 😉

Внимательный читатель, прочитавший весь рассказ, наверняка отметил, что среди рассмотренных самодельных проектов как будто чего-то не хватает 😉 А именно: нет полноценного цветного принтера (например, струйного), печатающего по цветовой модели CMYK! Хотя учитывая наличие в продаже высокоскоростных форсунок (например, легко можно взять инжекторные от автомобиля), подобное устройство не является чем-то заоблачным, но, тем не менее, автору его не удалось найти…

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

Кроме того, нужно отметить, что рассказ о сервоприводах выше был не просто так. Автору в своё время пришлось иметь дело с японскими режущими плоттерами, приводимыми в движение скоростными сервоприводами. Несмотря на то, что в них не использовались шаговые двигатели, система работала очень точно, быстро, с минимальным уровнем шума (если сравнивать с шаговыми приводами).

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

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

Играй в нашу новую игру прямо в Telegram!


ссылка на оригинал статьи https://habr.com/ru/company/ruvds/blog/712068/

Data driven SRE

Начнем эту увлекательную историю издалека. Во время первого локдауна, в начале 2020 года, сайт Леруа Мерлен испытал бóльшую нагрузку, чем когда-либо. Проводившие много времени дома и на даче наши пользователи взялись чинить полочки, проектировать новые кухни и всеми силами делать свой дом уютнее, воплощая в жизнь новые ремонтные проекты, а инженеры были вынуждены экстренно адаптировать системы под небывалый наплыв трафика. Тогда же стало ясно, что начатое незадолго до локдауна внедрение элементов SRE нужно ускорить.

Привет! Я Дмитрий Шувар, руководитель направления SRE Леруа Мерлен в России.

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

Мы говорим о SRE как о работе с системами с точки зрения пользователя.

Одна из задач инженеров по надежности — управление уровнем сервиса. Это помогает минимизировать влияние, частоту и вероятность повторения инцидентов.

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

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

  1. Как клиенты используют ваши системы и что важно для них?

  2. Каково отношение команд к инцидентам? Какие уроки извлечены? В командах доверительные отношения? 

  3. Принимаются ли решения, которые основаны на данных?

Ключевые метрики

Согласно классическому подходу, при внедрении SRE первым делом надо определить SLI, SLO и SLA. К сожалению, у нас так не получилось. Во время локдауна нам надо было сфокусироваться на системах, а не составлять документы, поэтому сначала мы потушили все пожары и масштабировали все, что только можно. Показателями занялись позже: выработали подход, подготовили шаблоны и стали ходить по командам, объяснять потребность, собирать данные. 

В Леруа Мерлен более 100 команд, сфокусированных на разработке приложений и инфраструктуре для наших продуктов и сервисов, поэтому процесс идет до сих пор. Кто-то определился, а кто-то еще размышляет, что же является для их систем SLO и какие SLI они считают ключевыми.

Многие спрашивают, что эти аббревиатуры означают и зачем они. 

Говорим примерно следующее: 

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

SLI — это количественные показатели, которые часто агрегируются по окну измерения и выражаются в виде доли, среднего значения или процентиля. 

Обычно SLI — это отношение двух чисел: количество хороших событий, деленное на общее количество событий. 

Например, вы можете посмотреть количество успешных HTTP-запросов / общее количество HTTP-запросов. Значение SLI будет варьироваться от 0% (ничего не работает) до 100% (ничего не сломано).

Чтобы помочь командам определить SLI, мы решили для начала взять подход, используемый в Google, — те самые «four golden signals» (latency, traffic, errors и saturation).

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

Traffic измеряет скорость запросов за определенный период времени.

С помощью Errors измеряют количество неудачных запросов.

Saturation измеряет количество запросов, которые система обрабатывает в данный момент.

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

К сожалению, в первые итерации получается определить лишь часть из этих показателей, и стоит зафиксировать хотя бы их. Рекомендация есть слона по кускам, а не всего за раз тут к месту. Например, нам пришлось отбросить один из сигналов. Определить показатели saturation, чтобы они отображали доступность сервиса для потребителя, — достаточно трудоемкая задача, и мы решили временно отложить ее, чтобы сконцентрироваться на оставшихся трех. Дальше мы долго говорили с командами об SLO и начали работать над процессом и инструментами для работы с нашими целями надежности.

Что дальше? Откуда брать эти SLI?

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

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

Пример uml-диаграммы
Пример uml-диаграммы

Теперь давайте поговорим про техническую часть. Это нужно, чтобы мы понимали друг друга и имели общую терминологию. Мы собираем метрики приложений, метрики обычно хранятся в TSDB, а чтобы получить общее понимание метрик в этих ваших системах хранения и мониторинга, давайте объясним, из чего оно состоит. Обычно это value, sample, metric и time series.

Value — это значение, которое на любом континенте значение, фактически это результат измерения. Например, 100500 HTTP-запросов, которые сервис получил с момента старта.

Sample — это value + timestamp. Например, 100500 HTTP-запросов, которые сервис получил с момента старта, измеренных 2022-12-31 16:30 UTC.

Metric — это уникальный идентификатор измеряемого ресурса. Он состоит из имени семейства метрик с прикрепленными к нему лейблами. Например, http_requests_total{pod=»billing-1″} и http_requests_total{pod=»delivery-2″} — это две разные метрики из семейства метрик http_requests_total.

Time series (чаще «series») — это Metric + любое количество связанных Sample с этим id. Например, http_requests_total{pod=»billing-1″} с семплами 700@16:30:00 UTC, 800@16:30:15 UTC, 900@16:30:15 UTC и т. д.

Active time series (чаще «active series») — это Metric, которая записала хотя бы один семпл за последние 20 минут.

Теперь давайте вернемся к более простым вещам.

SLO — это четко определенные, конкретные цели или обещания для доступности системы.

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

Мы считаем, что SLO — это внутреннее обещание уровня качества системы, которое должно быть достигнуто. Раз это обещание, то оно может быть приватным и публичным. Но мы считаем хорошей практикой публиковать его для соседних команд. Это помогает понимать зависимости и помогает в планировании работы в будущих спринтах на основе данных.

Но для абстрактного счастья пользователей недостаточно просто собирать данные, дальше потребуется определиться с Error budget и Burn rate.

Бюджет ошибок — это количество ошибок (обусловленных SLI), которые вы можете иметь за определенный период времени, это зависит от выбранных значений SLO, если вам лень считать в голове, есть калькулятор (https://uptime.is/). 

Burn rate — это скорость расходования бюджета ошибок. Мы используем это как один из подходов к оповещению для работы по управлению нашими SLO как обещаниями и уровнем сервиса, который мы пообещали. От скорости, с которой вы расходуете свой бюджет ошибок, зависит, что планировать на следующий спринт и на чем должен быть фокус команды.

Вообще, справедливо говорят, что истории из книг по SRE работают только в Google. На бумаге все выглядит красиво, но на практике оказывается, что это работает только у них. И тем не менее это отличная идея, которую они продвигают: вам не нужно выставлять сотни показателей на дашборд, для начала хватит и одного значения SLO по доступности.

Если недостаточно 4 золотых сигналов, то можно использовать и другие индикаторы.

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

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

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

Как еще повысить надежность приложений, независимо от их языка или платформы? 

Для приложений некоторые из распространенных методов включают изоляцию компонентов, реализацию стратегий самовосстановления, а также выполнение периодических проверок.

Классическая история: пользователь жалуется на доступность сервиса, конечно же, выясняется, что у всех в команде «все работает! вот же зашел, все открывается!». Однако пользователя не волнует, что у конкретной команды одного из микросервисов все работает. У него не работает, он не получает сервис. Доступность сервиса у пользователей — это главный приоритет с точки зрения SRE. Это очень важный момент, и он требует перестройки образа мышления.

Чтобы наблюдать систему «глазами пользователя», обычных систем мониторинга недостаточно. Всегда можно поднять условный мониторинг и увидеть, что поды рестартятся или оперативная память занята на 90%, но это обычно не имеет никакого значения, если пользователь не может заказать товар, например елку на Новый год, или видит заглушку, которая просит его выключить впн. Если поды рестартятся — это нормально, если память занята за 90% — это тоже нормально. Пользователи этого даже не заметят, ведь это не является ситуацией отказа. А вот если у пользователя недоступна корзина — это проблема.

Чтобы помочь коллегам легче ориентироваться в многообразии инструментов Observability стека и избавить от нужды поднимать свой собственный «внутрикомандный» комплект сервисов, еще в самом начале пути мы зафиксировали конкретный стек таких инструментов (https://tech.leroymerlin.ru/stack/ ), чтобы причесать достаточно разнообразный набор то тут, то там используемых продуктов. Для сбора метрик мы используем комбинации из white-box и black-box мониторинга, синтетические проверки, системы real using и application Performance мониторинга, системы сквозных трассировок и множество других систем, которые помогают нам минимизировать влияние инцидентов, найти корневые причины и снизить все четыре MTTR*.

R в данном случае может означать решение (repair), реагирование (respond), устранение (resolve) или восстановление (recovery), в зависимости от контекста.

Запросы на изменения

Давайте поговорим об изменениях и о том, как ими управлять. Мы любим и ценим процесс RFC (request for change) — запросов на изменения

*Термином «RFC» мы называем одновременно и процесс, и артефакт в виде документа.

Когда команда одного сервиса хочет внести изменение в продакшен, она должна получить одобрение от команд зависимых сервисов. Например, кто-то говорит: «Наша команда хочет выкатить изменение, которое затронет изменение API контракта с другим сервисом». Его зависимости отвечают: «Нет, в это время у нас трафик, давай перенесем». Они договариваются о подходящем времени и только тогда вносят изменения. RFC — неотъемлемая часть SRE.

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

Каждое изменение должно быть согласовано, но это в идеальном мире. У нас запрета на деплой без согласования нет, кроме времени, когда у нас фриз, обычно это новогодние и майские праздники. Например, в классическом подходе SRE-инженеры внедрены в продуктовые команды, проводят код-ревью и могут наложить на релиз или любое другое изменение вето.

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

Чек-листы

Однажды наступает день, когда ты думаешь, что неплохо было бы иметь чек-лист с проверками готовности к продакшену.

Production readiness — это вновь и процесс, и документ, позволяющие начать проектирование надежности сервисов в продакшене. Результатом работы является документ со списком выявленных проблем, что в долгосрочной перспективе должно уменьшить трудозатраты и риски, с которыми может столкнуться продукт.

Хорошо составленный чек-лист является важным компонентом readiness’ов.
Надо не пытаться сделать идеальный чек-лист, а с помощью здравого смысла и прошлого опыта определить важные темы для обсуждения. Цель состоит в том, чтобы заполнить пробелы, которые могут представлять значительный риск, а не в том, чтобы разработать чек-лист, который может покрыть все.

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

Применяемые лучшие практики и состояние продуктов должны учитываться при создании чек-листа, который дает конкретную, полезную информацию, развивающую обратную связь. Слишком большое увлечение лучшими практиками и рекомендациями (например, обсуждение используемых шаблонов проектирования кода) может стать скользкой дорожкой, медленно превращая readiness’ы в обзор архитектуры с несколькими практическими предложениями.

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

Такие подходы повсеместно используются в Google, Spotify, Ringcentral, Grafana, Weaveworks и в других технологичных компаниях.

Чек-листы — это база для будущей автоматизации.

Хорошей практикой является публикация своего чек-листа. Это может быть как страница в системе хранения знаний внутри компании, так и репозиторий на github.

Инциденты, много их, а я храбрый апельсин

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

Например, влияние (impact) может быть внутренним, или инфраструктурным, а может и оказывать негативный эффект на опыт пользователей.

Если произошел инцидент, инженер должен ответить на 3 вопроса.

  • Что случилось?

  • Какое влияние?

  • Какие следующие шаги?

После этого следует принять несколько решений.

  • Открывать инцидент или это не инцидент вовсе?

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

  • Возможно, выделить больше ресурсов (привлечь другие команды/экспертов)?

В Леруа Мерлен мы также следуем процессу управления инцидентами. Мы начали с определения приоритета уровня инцидентов и назвали их p1/p2 или major/minor соответственно, но если вам нравится определять приоритет цветами, размерами футболок или применить любую другую шкалу для изменения, вам никто этого не запретит. После мы подошли к определению ролей, таких как координатор, инцидент-менеджер. Важно заметить, что наш процесс управления инцидентами плавно перетекает в расследование и составление постмортема, в результате чего образуется план действий, о котором расскажем дальше.

Постмортемы — это хорошо

Как известно, хороший постмортем — это заполненный постмортем.

Postmortem (или root cause analysis report) — это снова и процесс, и документ для исследования инцидента и определения причин его возникновения. Он помогает выявить слабые места в системе и разработать меры по их устранению, чтобы избежать повторения подобных ситуаций в будущем. 

Postmortem является частью процесса управления надежностью системы и обычно включает в себя следующие шаги.

  1. Сбор информации об инциденте: время и дата возникновения, детали проблемы, какие сервисы и компоненты были затронуты.

  2. Определение причины инцидента: поиск корневой причины проблемы и выявление любых факторов, которые могли ее спровоцировать.

  3. Разработка плана действий: составление списка мер, которые необходимо предпринять, чтобы устранить проблему и предотвратить ее повторение.

Наверное, самая интересная часть после расследования произошедшего заключается в последующем плане действий. И тут открыт спектр подходов. Например, как это исправить для сервиса. Как подойти к плану с точки зрения системного дизайна. Как масштабировать ваши изменения на похожие типовые сервисы. Где еще в компонентах есть вероятность повторения точно такой же ошибки. Как начать новую инициативу, если она выходит за границы задачи на спринт.

Пусть это будет дружеским напоминанием: если у вас нет процесса и подробных документов, то самое время попробовать их в своих командах. Это весело!

И ретроспективы тоже

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

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

Базовое правило для ретро и постмортемов — это безобвинительная риторика. Это позволяет взрастить доверие ваших котанов.

Внутри Леруа Мерлен у нас есть периодические факап-митапы. Мы проводим их вживую и используем пиццу и интересные истории об инцидентах как точку притяжения. Цель митапа — показать, что ошибаются все человеки, понять, какие выводы мы сделали после каждого из происшествий, как действовали во время. Это помогает показать, что инциденты — это нормально, не стоит их бояться, но нужно быть к ним готовым.

Колесо неудачи

Следующая лучшая практика, которая поможет вашим инженерам быть выше, сильнее и сеньернее, это проведение мысленных экспериментов. «Что?! — скажите вы. — Работы на полгода вперед, а он тут мысленные эксперименты предлагает!» Но это вовсе не шутка.

Wheel of Misfortune (https://github.com/dastergon/wheel-of-misfortune) — это хороший повод собраться вместе и порисовать графики

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

Тренировка инженеров — это в первую очередь весело…и полезно.

Саммари

Спасибо, что посмотрели мемы с котами. За один раз сложно описать весь объем работы, который был проделан за несколько лет инженерами и менеджерами в Леруа Мерлен. Мы активно развиваем SRE-практику в компании, проводим внутренние обучения, улучшаем процессы и сервисы, управляем уровнем наших сервисов на основе SLO, RFC, Production readiness аудитов, истории наших инцидентов и детальных постмортемов, а также ищем и нанимаем талантливых инженеров.

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


ссылка на оригинал статьи https://habr.com/ru/company/leroy_merlin/blog/712960/

Виброакустический мониторинг дорожной обстановки

В России впервые в мире внедрили систему акустического мониторинга по волоконно-оптическим линиям на действующей автомобильной дороге протяженностью около 240 километров. Проект был реализован компанией «СМАРТС» в Самарской области на участке трассы федерального значения M-5 «Урал» при поддержке Российского фонда развития информационных технологий.  Система позволяет в режиме реального времени отслеживать большое количество событий на дороге с точностью до 1 метра по акустическим следам от участников дорожного движения. 

Для реализации программной части системы компании «СМАРТС» понадобился технологический партнер, которым стала российская ИТ-компания Haulmont.

В рамках этого проекта мы разработали на платформе JMIX (ранее – CUBA Platform) программное обеспечение – Автоматизированную Информационную Систему «Акустический мониторинг» (АИС АМ). Система реализует функции сбора, аналитики и хранения данных, а также рабочие места пользователей и администраторов системы. 

Чтобы достичь поставленных целей, нам пришлось погрузиться в новую предметную область и задействовать целый букет разнообразных технологий — Kafka, Zookeeper, Hazelcast, Hadoop Hive, Yandex Clickhouse, Grafana, Prometeus, PostgreSQL и другие; также нам понадобилось создать и обучить несколько типов нейронных сетей, без которых в такого рода проектах обойтись невозможно. 

IoT-датчик длиной десятки километров

Во вселенной Фрэнка Герберта “Дюна” на планете Арракис жили гигантские черви, которые чувствовали малейшую вибрацию песка. С технической точки зрения можно представить, что у такого червя был встроенный распределенный акустический сенсор (Distributed Acoustic Sensor, DAS), который позволял ему обнаружить и распознать источник вибрации. Ну а что происходило дальше, вы знаете. В наших широтах по причине высокой влажности эти существа, к счастью, не обитают, однако сама идея улавливать очень слабые вибрации в грунте и, анализируя их, определять, где и что шумит, может быть весьма плодотворной. Вместо инопланетной формы жизни берем оптоволокно, закапываем его в землю, светим в него лазером и по искажению сигнала вследствие деформации волокна из-за колебаний почвы определяем, что за событие произошло. По сути, оптический кабель становится очень длинным IoT- датчиком, на основе которых создают системы виброакустического мониторинга. 

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

Вспоминаем физику: почему небо голубое?

Прежде, чем двинуться дальше, любознательный читатель непременно задаст вопрос: «А как это работает?»

В основе метода виброакустического мониторинга лежит физическое явление рассеяния света на объектах, размеры которых меньше длины волны. Открыл его в 1871 году настоящий британский ученый Джон Уильям Стретт, и в том же году он женился. Как принято среди ученых, явление назвали в честь первооткрывателя – «рэлеевское рассеяние». Да-да, Джон Уильям Стретт и есть тот самый лорд Рэлей, просто титул лорда он унаследовал от отца два года спустя и в науке прославился уже под этим именем. Кстати, голубой цвет неба объясняется именно этим эффектом, потому что воздух рассеивает свет с короткой длиной волны сильнее, чем с длинной. Получается, что красные и желтые лучи от Солнца, игнорируя атмосферу, попадают нам в глаз, а синие разбегаются по всему небу, и мы видим их многократно отраженными. Прямой солнечный свет выглядит белым, потому что часть синих лучей избегает рассеяния, образуя полный спектр. 

Однако от понимания физического эффекта до его практического использования в методе когерентной рефлектометрии – дистанция огромного размера. Прежде надо было изобрести лазеры и микроэлектронику, чтобы построить приборы, способные этот эффект регистрировать. Поэтому распределенное акустическое зондирование стали применять только с 1970-х годов, сначала в нефтегазовой отрасли для мониторинга трубопроводов и защиты периметра. И лишь с середины 2010-х годов появились решения для мониторинга железных дорог, а затем и автомобильных. Дело в том, что в задачах типа охраны периметра происходят редкие события, которые отлавливать относительно просто. А если по дороге движется поток транспортных средств, то датчиком генерится огромное количество данных – и пришлось подождать, пока созреют и станут коммерчески доступными технологии Big Data, чтобы такие системы стали экономически рентабельны.

Слушаем шум дороги

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

В первой версии системы мы брали уже готовые события от поставщика датчиков. Разумеется, под капотом трудится нейросеть и затем определяется разброс значений и средняя скорость транспортного потока, подсчитывается количество событий таких как образование затора, съезд на обочину, ведение дорожных работ, проникновение в кабельные колодцы и многое другое. Также в акустическом сигнале видны аварии – во-первых, по резкому всплеску; во-вторых, после аварии изменяется скоростная характеристика всего потока, потому что остальным водителям приходится притормаживать. 

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

Нужны не только уши, но и глаза

Львиную долю информации об окружающем мире мы получаем благодаря зрению. Умные дороги тоже сначала обзавелись зрением – комплексы фотовидеофиксации давно стали привычными. Но слепых зон на любой трассе еще достаточно, поскольку хорошие камеры стоят дорого и на каждом столбе их не повесишь. С другой стороны, даже там, где камер нет, акустический датчик может зарегистрировать превышение скорости или другое нарушение – обгон в неположенном месте, съезд на обочину и так далее. Но вот беда – он не видит номер машины!

Глазами системы стали двенадцать стационарных и две мобильные камеры, передающие поток событий и видео в онлайн-режиме. Теперь, комбинируя акустику с картинкой, при расследовании аварий система пытается довести трек до зоны видимости камер.  И хотя данные, снимаемые с акустического датчика, носят вероятностный характер, по ним нельзя абсолютно точно определить автомобиль, эта информация может быть полезна. Но главное не в этом. Камеры помогают собрать обогащенный датасет для обучения нейросети, чтобы значительно улучшить качество распознавания треков автомобилей и «ассортимент» событий. Возможно, это станет таким же революционным шагом в обеспечении безопасности дорожного движения, как переход от немого кино к звуковому. Но об этом чуть ниже. 

Строим конвейер данных  

Итак, на входе у нас есть данные от виброакустических датчиков и с камер фотовидеофиксации. От датчиков поступает 30-70 млн событий в сутки, то есть примерно 350-800 в секунду плюс события и видеозапись с камер. И это только опытный участок, дальше будет больше – на втором этапе ожидается поток данных в формате HDF5 примерно 2 ТБ в час с одного датчика.

Поэтому подсистему сбора мы реализовали на Apache Kafka, чтобы принимать данные в темпе их поступления. Для этого мы использовали ряд адаптеров, основанных как на родных коннекторах Kafka от Confluent, так и на собственных на базе SpringBoot, которые интегрируются с различными API, получающими события по протоколам HTTP Live Streaming и WebSocket. Затем топики обогащаются при помощи Kafka Streams, черпая информацию из распределённого кэша Hazelcast. На выходе данные при помощи сервисов на базе SpringBoot и иных синкеров отправляются в PostgreSQL для оперативной работы пользователей, Apache Hive для долгосрочного хранения в исходном формате и Yandex Clickhouse для статистической обработки событий в BI-системе.

Весь пайплайн снабжен метриками, которые на разных этапах собираются Prometheus, визуализируются с помощью Grafana, а в критических ситуациях система оповещает разработчиков и пользователей через Telegram.

Учим свою нейросеть

На первом этапе мы получали события «из коробки» – только те, что формируются оборудованием виброакустических датчиков. И хотя в рамках проекта данное оборудование активно дорабатывалось, такая схема взаимодействия не позволяет в полной мере раскрыть потенциал комплексного решения. 

Поэтому сейчас, на втором этапе, который должен завершиться в 2023 году, ведется разработка собственного модуля нейросетевого распознавания. На входе он будет получать сырые данные с датчиков, а на выходе позволит отслеживать треки движения автомобилей на большей протяженности (без потери трека из-за помех, обгонов или движения в колонне), получать более точную статистику потока автомобилей, детектировать аномалии движения (аварии, изменения скорости потока из-за временных или постоянных помех, включая выезд дорожной техники или деградацию полотна дороги), автоматически определять остановки, обгоны в неположенном месте с возможностью определения наиболее аварийно-опасных участков с большим числом нарушителей. 

Выявляем треки движения и определяем события

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

Далее используется сверточная нейросеть архитектуры U-Net (112 слоев, 35 из которых сверточные). Исходное изображение акустического сигнала при проходе через первую половину слоев сжимается по высоте и ширине, но увеличивается по числу каналов (каналы теперь содержат «признаки» объектов на изображении), и при проходе через вторую половину слоев изображение восстанавливается до исходного размера и на нем будут отрисовываются треки автомобилей.

За поиск точечных событий, например, остановок ТС, отвечает YOLOv5 – одна из наиболее современных и эффективных моделей в классе Object Detection. Особенность моделей YOLO (you only look once) в том, что они принадлежат к классу one-stage детекторов, то есть, изображение необходимо пропустить через нейронную сеть только один раз, что дает ощутимый выигрыш во времени.

Кратко описать принцип ее работы можно так: изображение разбивается на небольшие области, каждая из этих областей возвращает шесть чисел – номер класса, уверенность модели в этом классе, координаты центра, а также ширину и высоту прямоугольника. С помощью метода Non-maximum Supression выполняется фильтрация выделенных областей и удаляются дубликаты – иначе было бы много ложных срабатываний.

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

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

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

Такие аномалии скорости могут образовываться по различным причинам, охватывая разные временные и пространственные интервалы. Это значит, что необходимо иметь инструмент, который позволит быстро создавать и модифицировать алгоритмы расчета; при этом он должен обеспечивать наглядность и простоту сопровождения. Посмотрев, что есть на рынке, мы склонились в пользу Apache NiFi – ETL, который вполне можно отнести к классу Low-code решений. С его помощью в системе реализован сбор усредненных метрик, предварительная агрегация поступающего потока данных, сравнение поступающих данных с накопленными и поиск аномалий. Результаты работы его алгоритмов при помощи Kafka сохраняются в PostgreSQL. 

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

Я милого узнаю по походке…

Акустический сенсор умеет «узнавать» конкретный автомобиль по его fingerprints. Переводить это как «отпечатки пальцев» здесь не совсем уместно – однако термин “фингерпринт” в его русском написании уже прижился, когда говорят об уникальных характеристиках чего-либо, например, браузера на вашем компьютере, или, в нашем случае, трека автомобиля. 

Реалии таковы, что мы не можем получить непрерывный трек движущегося транспортного средства из-за помех. Если мы «ведем» легковой автомобиль, то он может исчезнуть в акустической тени какого-нибудь КАМАЗа и затем появиться снова. В итоге вместо сплошной линии мы имеем некий пунктир, и надо решить, относятся ли соседние фрагменты трека к одному авто или к разным. Задача решается в два действия:

Сначала с помощью EfficientNet получаем фингерпринты для каждого фрагмента трека. На втором шаге с помощью многослойного линейного классификатора (25 слоев, 6 из которых полносвязные) вычисляется вероятность совпадения двух фингерпринтов. В результате получается наглядная картинка – зеленые линии показывают, что текущая часть трека по фингерпринту соответствует начальной, красная – не соответствует.

Визуализируй это

BI-часть системы строится на очень удачной коллаборации Clickhouse и Grafana. Разработанная в Yandex колоночная аналитическая СУБД Clickhouse легко развертывается и настраивается для приема миллионов строк данных ежесуточно и не требует значительных затрат на сопровождение. На текущий момент в Clickhouse накоплено 20 миллиардов записей. 

Так как Clickhouse отвечает только за хранение данных, не предоставляя пользователям никакого интерфейса, потребовалось найти инструмент для людей. Нами были протестированы Apache Superset, Redash и Grafana и для нашего кейса работы выбор однозначно пал на последнюю. 

Как инструмент визуализации данных мониторинга инфраструктуры Grafana предлагает богатые средства работы с временными рядами, – а это именно то, что более всего нужно пользователям системы. Для этого мы настроили более двадцати дашбордов со множеством аналитических панелей. 

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

А вот так на двумерной «тепловой карте» скоростей выглядит воскресная вечерняя пробка на въезде в г. Самара в летнее время, когда люди возвращаются с дач в город в конце выходных:

Одномерный мир в проекции на глобус

Пользователи работают с системой через веб-интерфейс в приложении на Java-платформе JMIX (ранее – CUBA). В принципе это довольно обычное корпоративное приложение, коих в Haulmont было разработано великое множество. Базовая функциональность по работе с объектами, администрирование, управление пользователями, безопасность, полнотекстовый поиск и другие стандартные блоки реализуются средствами платформы. 

Однако с точки зрения разработки, пожалуй, здесь можно отметить несколько особенностей. Во-первых, все события, о которых мы говорили ранее, происходят фактически в одномерном мире – внутри оптоволоконного кабеля. И логичным образом возникает задача отображения этой информации на реальный мир – то есть, на карту. Оптоволокно лежит вдоль дороги, которая отнюдь не является прямой и кроме того, оператору нужно видеть, где расположены прочие объекты – дорожные знаки, АЗС, съезды и развязки и так далее. Поэтому в составе решения появилась ГИС на основе GeoServer и взаимодействие с картой составляет существенную часть работы оператора. В дополнение к этому заказчик с помощью промышленного квадрокоптера произвел аэрофотосъемку автомобильной дороги с прилегающими территориями в HD качестве, так что пользователь может буквально видеть каждый метр трассы – для чего тоже понадобилась разработка соответствующего модуля. Второй особенностью можно считать интенсивное использование инструментов BI, что также потребовало создания специфических интерфейсов и ряда интеграций.

В целом система позволяет по-новому видеть дорожную обстановку — для нее нет полностью слепых зон. Эта информация пригодится для анализа скоростных статистик, поможет в расследовании инцидентов, позволит следить за состоянием самого дорожного полотна. 

Конечно за событиями на дороге удобнее следить через видеокамеры и призму видеоаналитики, но оптический кабель – это пассивный сенсор, который не требует подключения к электроэнергии и может быть сенсором на рубежах до 100км. А камеру не установишь без подключения к электроэнергии, количество этих камер требуется огромное количество. На магистральных дорогах проблематично каждые 500м найти точку подключения к электропитанию. 

Но существующие камеры могут существенно обогащать данные автоматизированной информационной системы «Акустического мониторинга» (АИС АМ). Информация с камер на подъезде или выезде участков дорог с АИС АМ помогают привязать дополнительную информацию к треку движения транспортного средства (акустическому следу) – к примеру государственный регистрационный номер, цвет, марку. Таким образом это будет след не «неизвестного транспортного средства», а вполне определенного, что позволит с большой точностью разбирать дорожно-транспортные происшествия и помогать в оперативно-следственных мероприятиях.

Комплекс виброакустического мониторинга автодорог впервые в мире внедрен именно России и количество сценариев его использования будет постоянно расти. Будем держать вас в курсе! Как внедряется и работает система можно посмотреть в ролике.  

Все это далеко выходит за рамки обычных корпоративных систем, которые мы регулярно делаем на нашей платформе JMIX.  Система разработана и успешно внедрена в Самарской области на серверном оборудовании «СМАРТС». В настоящий момент можно поделиться полученным опытом и некоторыми планами дальнейшего сотрудничества Haulmont и «СМАРТС» по развитию данного решения.  В 2023 году у заказчика большие планы на расширение возможностей АИС АМ и её интеграции с не менее интересным программно-аппаратным комплексом ПАК «Умная дорога» (в основе которого лежит технология V2X – коммуникация автомобилей между собой и с дорожной инфраструктурой). Скоро наши автомобили и дороги станут умными и смогут значительно больше, чем информировать о пробках. Конечно, АИС АМ будет одной из ключевых информационных систем об обстановке на дороге, для реализации большого количества кейсов V2X.


ссылка на оригинал статьи https://habr.com/ru/company/haulmont/blog/712788/