Дракони ІТ-галузі: Забезпечення якості нейромережевих продуктів
Вступ
Не так багато часу минуло з моменту виходу першої статті циклу про драконів ІТ-галузі, як друга вже пропонується до розгляду. І якщо в попередньому матеріалі мова йшла в основному про теоретичні підвалини світу ШІ (Що таке ШІ, ML, DL? В чому між ними різниця? А що таке нейронні мережі?…), то в цьому будемо говорити про процеси забезпечення та контролю якості для ШІ-продуктів загалом і зокрема для тих, що базуються на нейронних мережах (Як побудувати QA-фреймворк? В чому його особливості? Які є підводні камені? …).
Як ви вже зрозуміли, шановні читачі, даний матеріал, як і більшість з моїх статей, можна сприймати або як поліпшувач загальної ерудиції, або, якщо ви плануєте чи вже займаєтесь забезпеченням якості ШІ-софту, як можливий алгоритм дій. До речі, кадр з мультфільму «Як приборкати дракона» не випадково використано як титульне зображення, але про це трохи згодом.
Частина 1: Загальний підхід та базові перевірки
Якщо ми з вами справжні спеціалісти з забезпечення якості (на що я дуже сподіваюсь), то нам байдуже із чим працювати: зі скакалкою, піцою чи нейромережевим продуктом, бо кожний об’єкт має свою структуру і функціонал, спираючись на які можна досить легко звести одну велику задачу до декількох менших, але із вже відомими шляхами розв’язання, тобто девізом цього підходу можна вважати фразу «розділяй і володарюй». Пропоную застосувати цей підхід до нашої поточної задачі!
Цікавий факт:
Вчені не раз намагалися з’ясувати автора вищезазначеного крилатого виразу. Зазвичай його відносять до римського сенату, хоча він відсутній в класичних текстах античних часів. Натомість «розділяй і володарюй» зустрічається і в Макіавеллі: che tu hai in governo, divise («те, чим керуєш, розділяй»), і в «Звістках з Парнасу» Боккаліні: «divide et impera», навіть у романі «Три мушкетери» його вимовляє Людовик XI. Все ж таки на поточний момент, автор виразу залишається невідомим.
Почнемо зі схеми роботи нейропродуктів (тобто, як завжди, відштовхуємось від структури та функціоналу), в загальному випадку, вона виглядає так:

Сподіваюсь, задача більше не здається надважкою. На ілюстрації добре видно, що ПО, яке базується на нейронних мережах, в загальному випадку, є майже типовим представником мікросервісної архітектури. Тобто архітектурна особливість полягає лише в тому, що кожна окрема модель представлена власним мікросервісом.
За традицією, увесь продукт можна структурно розділити на дві частини: фронт і бек. Стосовно фронту, в залежності від типу додатка, можуть бути різні версії клієнтів: веб, мобільні та настільні. Якщо продукт великий, то версій клієнту може бути більше за одну, тобто будь-які дві, або навіть всі три.
Переходячи до бека, ми потрапляємо до API, тобто до інтерфейсу мікросервісів, до речі, в таких продуктах, зазвичай, використовується REST архітектура. Через цей API ми матимемо змогу взаємодіяти з усіма наявними мікросервісами, кожен з яких являє собою окрему модель, тобто окрему нейромережу, чи її версію, що має виконувати певні функції.
Також до мікросервісів під’єднані власні бази даних, які зберігають вже оброблені результати. Якщо ж у продукті ведеться облік дублікатів, то саме бази даних дозволяють зайвий раз не напружувати систему, просто підтягуючи вже колись згенеровану відповідь.
Таким чином, тимчасово абстрагувавшись від перевірки самого мікросервісу, ми приходимо до того, що все зводиться до класичного веб/мобайл/десктоп тестування, REST-API тестування та тестування баз даних (SQL нам в допомогу).

Далі пропоную виокремити основні види тестування, які обов’язково варто провести на нейромережевих проєктах:
- функціональне тестування (functional testing) – Картинки створюються? Текст генерується?
- нефункціональне тестування (non-functional testing)
- навантажувальне тестування (load testing) – Скільки часу треба для відповіді?
- стрес-тестування (stress testing) – Скільки часу пропрацює при «напливі» користувачів?
- тестування стабільності (stability testing) –Скільки часу може максимально пропрацювати?
- тестування зручності використання (usability testing) – Чи зрозуміло пересічному громадянину, як користуватись?
- тестування інтерфейсу користувача (ui testing) – Чи все є у графічному інтерфейсі?
- тестування безпеки (security testing) – Чи можна отримати дані інших юзерів без дозволу?
- тестування локалізації (localization testing) – Чи правильно відображається час у користувачів з різних часових поясів?
- тестування сумісності (compatibility testing) – Чи на всіх потрібних пристроях працює продукт?
- тестування, пов’язане зі змінами:
- Димове (smoke testing) – Чи немає у новій версії очевидних помилок?
- повторне тестування (re-testing) – Чи виправлено проблему?
- санітарне (sanity testing) – Чи правильно працює функція після незначних змін?
- регресійне (regression testing) – Чи немає «побічних ефектів» в новій версії?
- тестування за рівнями:
- компонентне тестування (unit testing) – Чи вірно працюють окремі компоненти?
- інтеграційне тестування (integration testing) – Чи вірно працює зв’язок між компонентами?
- системне тестування (system testing) – Чи вірно працює вся система?
- тестування при здачі (acceptance testing) – Чи все працює так, як хоче замовник?
- тестування за ознакою позитивності:
- позитивне тестування (positive testing) – Чи все працює так, як повинно?
- негативне тестування (negative testing) – Чи все не працює так, як не повинно?
- тестування за ступенем підготовленості:
- тестування за документацією (formal testing) – Чи все працює за специфікацією?
- дослідницьке тестування (exploratory testing) – Чи вважаю я, що все працює так, як повинно, базуючись на особистому досвіді?
Зрозуміло, що це далеко не повний перелік, і що на кожному проєкті є свої особливості (наприклад, мій поточний продукт Kebeta.ai не має власного UI, він з’являється лише після інтеграції до системи замовника), але тепер для вас, шановні читачі, тестування нейропродуктів більше не є таємницею за сімома печатками.

Частина 2: Особливості побудови QA-фреймворку та розвіювання міфів
Повертаючись до перевірки самого мікросервісу, варто поставити важливе питання: «Який рівень допуску мають QAшники на проєкті?». Хтось може запитати: «Це що, якісь силові структури? Може у вас ще «закриті» матеріали є?». Якщо відповідати серйозно, то кожен IT-фахівець, коли приходить на проєкт, підписує документ про комерційну таємницю, де погоджується не розголошувати ту інформацію про продукт, яка є конфіденційною і розголос якої може завдати збитків компанії. Тому кожен ІТвець володіє якоюсь «закритою» інформацією.
Цікавий факт:
Найпопулярніша у світі «закрита інформація» – формула секретного рецепта кока-коли, так званого препарату 7Х, який був винайдений в 1886 році фармацевтом з Атланти Джоном Пембертоном і від тоді зберігається в таємниці. Хоча на частку 7Х доводиться лише один відсоток змісту кока-коли, саме він надає напою унікальний смак. Формулою володіють лише дві людини у компанії, яким навіть забороняється літати одним літаком через ризик повної втрати рецепта в авіакатастрофі.
На нейропродуктах може бути два рівні допуску для QA-фахівців: із залученням до ML та без залучення до ML. Так, так, вам не почулось, на деяких проєктах певні етапи машинного навчання виконують QAшники, мова йде про тестування та валідацію (ці етапи все одно мають бути виконаними, а ось хто це буде робити: QA-фахівці чи Data Science-фахівці, то вже інше питання).
Коли фахівці з Data Science вивчили модель на тренувальному дата сеті, за справу беремося ми та перевіряємо результати навчання на тестувальному дата сеті, і якщо кількість помилкових рішень перевищую заздалегідь встановлену норму, то виявляються приблизні групи нейронів, звідки почались помилки, і всі ці результати передаються тим же самим фахівцям з Data Science.
Якщо ж тестування успішно пройдене, то переходимо до наступного кроку, запускаючи валідаційний дата сет, і знов рахуємо кількість помилкових рішень або по-інакшому точність моделі (точність = кількість правильних рішень/загальну кількість рішень): якщо точність висока, то модель затверджується і «виливається» до тестового середовища, якщо точність низька, то знов повертаємо модель хлопцям з Data Science.
Мені здається, що рівні доступу QA-фахівців доречно порівняти із box-тестуванням: без ML – black box testing (ані гадки не маємо як воно працює, просто знаємо, що на вході та що на виході), з ML – white box testing (знаємо усі нюанси внутрішнього устрою і навіть там копирсаємось), але є ще grey box testing, що є сумішшю двох попередніх видів (знаємо лише певні нюанси внутрішнього устрою, але тестуємо з позиції користувачів).

Так, питання залучення до ML процесів тестувальників досить дискусійне, але на поточний момент все залежить від компанії, наприклад на моєму проєкті реалізовано варіант із grey box testing, тобто без залучення до ML, але ключові моменти внутрішнього устрою відомі.
Єдине, що є спільним на всіх гарно організованих проєктах — чітке розділення обов’язків: навіть на тих проєктах, де тестувальники залучені до ML, це буде окрема команда або одиничні фахівці виключно під цей процес, бо інакше замилюється око і такі тестувальники підсвідомо обходитимуть слабкі місця моделей.
Також хотів би зауважити, що важливим етапом організації процесів забезпечення якості є розуміння загального принципу роботи продукту, який, до речі, можна не розуміти навіть копирсаючись із ML. Звісно, можна стверджувати, що на співбесідах усі фахівці проходять жорсткий відбір і на такі продукти не потрапляють несвідомі, але в житті трапляється всяке.
Тому пропоную розглянути метод, який трохи підтягне навіть не дуже відповідальних колег – це візуалізація процесів (мається на увазі малювання схеми роботи, подивившись на яку навіть колега-новачок одразу зрозуміє ідею). Існує безліч варіантів реалізації вищезазначеного методу: від загальної, чорно-білої, майже шкільної схеми до величезних, кольорових діаграм, де згадуються усі важливі нюанси.
До речі, перше, що я зробив, коли прийшов на поточний проєкт – намалював загальну схему, яку згодом покращив і потім розділив на декілька частин, максимально деталізувавши усі процеси. Для реалізації таких схем існує безліч методів та інструментів, але я рекомендую саме diagrams.net та шаблони Microsoft, завдяки яким можна зробити щось на кшталт:


Далі варто торкнутись питання документації та процесу організації праці, які також зазнали деяких змін. Усі знають, як працювати писати на більш-менш типових проєктах: вивчаємо специфікацію, пишемо документацію (Test strategy, Test plan, Check list та Test cases), реалізуємо написане, фіксуємо результати, виявляємо недоліки, покращуємо виявлене, можливо, щось змінюємо у процесах, — але що не так із нейромережевими продуктами?
В цілому, робимо все те саме, що й завжди, хіба що враховуючи одну особливість – ніхто не може на 100% гарантувати поведінку нейромережі. Наприклад, була навчена та натренована певна модель, всі розраховували, що валідація пройде гарно, але раз, і на валідаційному дата сеті виявляється ще нижча точність, ніж була місяць тому, тому модель відправлять Data Scientistам на доробку.
Тепер треба збирати додаткові дата сети, писати додаткові тестові сценарії й взагалі доводиться змінювати робочий план, оскільки нової моделі в тестовому середовищі пару тижнів ще не буде. Інший приклад: на проді почали з’являтись неочікувані помилки в поведінці моделі й тепер треба не просто знайти причину, а ще й трохи довчити модель для уникнення подальших ситуацій, а це знов нові дата сети, нові сценарії та переліки перевірок і так далі.
Зрозуміло що, гнучкі методології на те і гнучкі, щоб відносно легко підлаштовуватись під обставини, але нейропродукти вимагають особливого виду гнучкості, тому будьте готові до раптових змін та доробки/перероблення документації (до речі, якщо дозволяє бюджет, рекомендую використовувати ПО для управління тестовими артефактами, наприклад, Test Rail, якщо ж ви на стартапі, то Excel/Google sheets – ваші найкращі друзі в цьому питанні).

Також треба висвітлити аспект працездатності нашого мікросервісу, бо навіть якщо ми перевіримо функціонал на 200%, це не дасть на гарантії, що все буде так же працювати під час активного користування. Як всі все здогадались, мова йде про performancetesting, тобто тестування продуктивності. Найнагальніші питання, на які ми повинні знати відповідь:
- Чи витримує наш продукт заплановану кількість користувачів?
- Скільки одночасних користувачів витримує наш продукт?
- Скільки часу пропрацює наш продукт під стабільним навантаженням?
- Який компонент системи зламається першим при збільшеному навантаженні?
Звичайно, перелік питань, на які треба відповісти, є значно більшим за наведений, але треба ж з чогось починати. Стосовно інструментів для performance testing, можу порекомендувати JMeter та LoadNinja.
Наостанок, хотілося б розвіяти декілька популярних міфів про штучний інтелект, якими, наче дітей бабайкою, лякають дорослих:

- Скоро ШІ замінить людей! Більша частина фахівців приречена!
Можливості програм, що використовують технології штучного інтелекту, тут явно перебільшенні. Так, нейромережі можуть виконувати деякі завдання та обробляти інформацію швидше за людину, але вони є інструментом, призначеним для полегшення роботи та підтримки прийняття рішень. Тому краще сказати, що люди, що використовують ШІ, замінять тих, хто їм не користується, але то вже мова про конкуренцію, яка завжди була на ринку.
- Скоро повстання машин, ховайся хто може!
Знову бачимо невиправдану паніку, бо ПЗ, що базується на технологіях штучного інтелекту, не знає як треба і просто робить те, чого навчили. Дійсно, через брак даних інколи буває так, що в дата сети додають інформацію, що була згенерована іншою моделлю, але це не означає, що вони вчать одне одного. Машина може запам’ятовувати, відтворювати та прогнозувати, але до створювання нового, виходу за рамки завдання та вбивства людей їй ще, як до Києва рачки, тому можна не хвилюватись.
- Штучний інтелект завжди правий та не може помилятись!
Так, ШІ може бути дуже потужним і здатним вирішувати складні завдання, які під силу далеко не всім людям, але він залежить від якості та кількості доступних даних, а також точності алгоритмів. Програмне забезпечення, що базується на технологіях штучного інтелекту, не просто може допускати помилки, особливо в незнайомих ситуаціях або при наявності неправильних даних, а майже завжди це робить в тій, чи іншій кількості, тому важливо розуміти його обмеження і слідкувати за якістю навчання і роботи моделей.
Підсумок
У цій статті ми обговорювали процеси забезпечення та контролю якості на нейромережевих продуктах та особливості побудови QA-фреймворку.
З початку мова йшла про філософію підходу («розділяй та володарюй»), далі розглядалась загальна структура нейромережевих продуктів (фронтенд, бекенд, мікросервіси), що будується відштовхуючись від функціонала та устрою (в цілому, як завжди).
Окремо розглянули основні види тестування, на яких варто зосередитись на нейромережевих проєктах (функціональне тестування, нефункціональне тестування, тестування, пов’язане зі змінами, тестування за рівнями, тестування за ознакою позитивності, тестування за ступенем підготовленості).
Далі перейшли до питання «рівня допуску» QA-фахівців (із залученням до ML та без залучення до ML), провівши аналогію із box-testing (black box testing – ані гадки не маємо як воно працює, просто знаємо, що на вході та що на виході; white box testing – знаємо усі нюанси внутрішнього устрою і навіть там копирсаємось; grey box testing – знаємо лише певні нюанси внутрішнього устрою, але тестуємо з позиції користувачів).
Обговорили аспект візуалізації (малювання схеми роботи), запропонувавши певні інструменти для реалізації (diagrams.net та шаблони Microsoft), та аспект посиленої гнучкості (ніхто не може на 100% гарантувати поведінку нейромережі), рекомендуючи різні методи ведення тестової документації (Test Rail та Excel із Google sheets). Висвітлили аспект перевірки працездатності (Скільки користувачів витримує? Що першим зламається), додавши можливі інструменти для реалізації (JMeter та LoadNinja).
Наостанок, розвіяли декілька найпопулярніших міфів про ШІ (Скоро ШІ замінить людей; Скоро повстання машин; Штучний інтелект завжди правий), якими вже декілька років лякають весь світ.
На завершення, хотілося б розкрити таємницю вибору титульного зображення. Мультфільм «Як приборкати дракона» має одну цікаву особливість, яку, з моєї точки зору, варто зрозуміти більшості початківців в IT сфері. Іккінг, як головний герой, значно відрізняється від більшості героїв тим, що в його образі відсутня ідея обраності, і він, по суті, сам провокує подію, яка дає йому змогу вступити на новий шлях та перевершити всіх.
Тобто, якщо ми хочемо стати справжніми спеціалістами, особливо в галузі IT, варто брати, розбиратись та робити (приборкувати драконів/ нейронні мережі/ нові QA-фреймворки й т.д.), не зважаючи на те, що ми не маємо статусу «обраних» чи «народжених для цього»!


