Wszystkie artykuły Research

Inżynieria AI

Kompletna aplikacja webowa od AI: eksperyment na sobie

Środowisko AI buduje groovebox w przeglądarce z własnym modelem perkusyjnym - a dziennik prac dokumentuje, co poszło dobrze i gdzie AI zawiodła.

1. Znalezisko

Domena mybytes.com jest wyraźnie starsza niż dzisiejsza spółka myBytes GmbH. Źródła historyczne pokazują, że pod adresem /mixer.html dostępna była kiedyś przeglądarkowa aplikacja muzyczna: Internet Archive prowadzi migawki tego URL-a od lutego 2008 do marca 2015 roku, a ówczesne relacje przypisują stronę kampanii Microsoftu poświęconej edukacji młodzieży w zakresie praw autorskich, zrealizowanej przez zewnętrzną agencję w technice tamtych czasów.

Dla porządku, bo to dla nas ważne: dzisiejsza myBytes GmbH nie ma z tamtą wcześniejszą ofertą żadnego związku organizacyjnego ani gospodarczego. Nie jesteśmy ani następcą prawnym, ani kontynuatorem; domena została nabyta dopiero później. Nic w nowej aplikacji nie przejmuje kodu, grafiki ani dźwięków dawnego produktu.

Nas interesowało coś innego: URL, który ponad piętnaście lat temu nosił przeglądarkowy mixer, leży odłogiem. Jak zbudowałoby się taką aplikację dzisiaj? I jak dużą część tej pracy może rzeczywiście przejąć współczesna generatywna AI?

2. Pytanie

Eksperyment zdefiniowaliśmy świadomie wąsko. Wspierane przez AI środowisko inżynierskie (Claude w Claude Code) otrzymało zadanie zbudowania pod /mixer.html prawdziwego grooveboxa: sekwencer krokowy, synteza, mikser, a w sercu model uczenia maszynowego, który generuje patterny perkusyjne i tworzy ich wariacje, działając w całości w przeglądarce użytkownika.

Podział pracy był ustalony z góry. AI projektuje, implementuje i dokumentuje; człowiek decyduje w zdefiniowanych bramkach: zatwierdzenia architektury, testy odsłuchowe, oceny designu, kwestie licencyjne. Każda sesja była protokołowana w dzienniku prac, a każde twierdzenie tego artykułu pochodzi z tych zapisów albo z danych pomiarowych udokumentowanego przebiegu.

3. Od zlecenia do wymagań

Z pomysłu powstał najpierw katalog wymagań: osiem ścieżek (docelowo dwanaście, w tym trzy tomy i ścieżka talerzy), siatka 32 kroków na dwa takty, transport z BPM i swingiem, dla każdej ścieżki głośność, panorama, mute i solo, do tego treści demo, które niosą stronę przy pierwszym otwarciu. Dla komponentu AI obowiązywała twarda zasada: model nie generuje przebiegów audio, lecz zdarzenia muzyczne - który instrument uderza na którym kroku i jak mocno. Generowanie dźwięku pozostaje w całości po stronie Web Audio API.

Dwa warunki brzegowe ukształtowały całą resztę. Po pierwsze: każdy dźwięk aplikacji jest syntezowany, nie ma obcych sampli, a więc i nieuregulowanych praw. Po drugie: inferencja działa lokalnie; przeglądarki nie opuszczają żadne dane audio ani treści muzyczne. Potwierdza to trace sieciowy kompletnej sesji (ładowanie, odtwarzanie, generowanie, wariacje): przesyłane są wyłącznie zasoby strony i pliki modeli przez GET; jedynym wychodzącym śladem danych są zdarzenia kliknięć własnej statystyki serwisu, która działa na każdej stronie i nie zawiera żadnych treści muzycznych.

4. Architektura

Aplikacja składa się z czterech warstw. Centralny store przechowuje pattern (kroki, nuty, ustawienia) jako jedyne źródło prawdy. Scheduler planuje zdarzenia audio; web worker tyka co 25 milisekund, a wątek główny planuje wtedy wszystkie zdarzenia najbliższych 120 milisekund z dokładnością do sampla względem zegara AudioContext. Silnik audio utrzymuje dla każdej ścieżki łańcuch gain i panoramy stereo, a przy starcie renderuje dźwięki perkusji z parametrów syntezy do buforów. Warstwa AI wreszcie ładuje dwa małe modele TensorFlow.js i zapisuje swoje wyniki do store'a, nigdy bezpośrednio do silnika audio.

Część schedulera to klasyk programowania audio w przeglądarce: kto wyzwala nuty przez setInterval, słyszy wahania timingu, gdy tylko przeglądarka przydusi kartę. Wzorzec lookahead (planowanie w przód na zegarze audio, tyknięcie w workerze) od lat jest utartą drogą i AI zaimplementowała go poprawnie za pierwszym podejściem.

5. Model: małe VAE dla patternów perkusyjnych

Sercem jest wariacyjny autoenkoder na symbolicznych patternach perkusyjnych - model, który zagęszcza wzorce do zwartej reprezentacji liczbowej i z niej znów generuje. Pattern to macierz 32 kroków i pięciu klas (stopa, werbel, zamknięty i otwarty hi-hat, perkusjonalia); wartości to siły uderzeń między 0 a 1. Enkoder odwzorowuje te 160 liczb na 32-wymiarowy wektor latentny, a dekoder rekonstruuje z niego pattern dwiema głowicami: jedna mówi, czy uderzenie następuje, druga - jak mocne jest.

Dlaczego VAE, a nie model autoregresyjny? Z powodu funkcji kluczowej. Wariacja istniejącego patternu jest w przestrzeni latentnej precyzyjnie definiowalna: zakodować pattern, przesunąć wektor o kontrolowany promień, zdekodować. Regulator wariacji w aplikacji odwzorowuje dokładnie ten promień. Pomiar potwierdza koncepcję: średnia zmiana patternu rośnie monotonicznie z promieniem, od 0,016 przy r = 0,1 do 0,192 przy r = 1,7, bez nasycenia w mierzonym zakresie.

Trening odbył się na Groove MIDI Dataset (Google, CC BY 4.0), prawdziwych nagraniach e-drum ludzkich perkusistów: 20 474 dwutaktowe okna z 1150 plików, podzielone według perkusistów (70,4 / 14,8 / 14,8 procent), tak aby żaden grający nie znalazł się jednocześnie w treningu i teście. Wybrany model ma 201 856 parametrów i trenował 70 epok w 12,3 sekundy na CPU - to nie literówka: w tej skali trening nie jest problemem infrastrukturalnym. Ablacja rozmiaru przestrzeni latentnej (8, 16, 24, 32 wymiary) dała wartości onset F1 równe 0,638, 0,710, 0,737 i 0,749; wybrano 32.

Wyeksportowane modele mają razem 397,4 kilobajta (fp16). Test zgodności przeliczył przebieg w przód bezpośrednio z dostarczonych wag w numpy; maksymalne odchylenie od środowiska treningowego wyniosło 0,0009.

Model raz urósł w trakcie projektu razem z produktem: gdy aplikacja dostała ścieżki tomów, powstała druga wersja modelu z ośmioma klasami (pięć dotychczasowych plus trzy tomy), z własnym seedem i własnym przebiegiem. Wcześniej stała bramka: pomiar obłożenia. Wszystkie trzy klasy tomów leżą w zbiorze danych poniżej poziomu i tak rzadkich otwartych hi-hatów (34,0, 17,4 i 28,9 procent okien wobec 38,1) - decyzja, by mimo to trenować i prowadzić tę rzadkość jako udokumentowany wynik, zapadła po stronie człowieka.

Łączny F1 spadł zgodnie z oczekiwaniami z 0,749 do 0,697 (cel ma trzy rzadkie klasy więcej), modele urosły łącznie do 542 kilobajtów, a test zgodności zakończył się maksymalnym odchyleniem 0,0012.

Style aplikacji to kotwice w przestrzeni latentnej - cztery od początku, piąta doszła jako konsekwencja jednego z wyników (rozdział 9). Z pierwotnych czterech dwie (Lo-Fi, Experimental) pochodzą z gatunkowych podzbiorów zbioru danych, dwie (House, Electronic) z kuratorowanych patternów referencyjnych. Różnica to osobna historia: podzbiór „dance” zbioru danych brzmiał obiecująco, ale składał się z zaledwie siedmiu nagrań dwóch perkusistów - kotwica z niego zakodowałaby te dwie osoby, nie gatunek. Decyzja o odrzuceniu tego podzbioru zapadła przy tym przeliczeniu - przed jakimkolwiek testem odsłuchowym i bez żadnej metryki modelu, która by ją wymuszała.

6. Web Audio: brzmienie bez sampli

Każdy dźwięk aplikacji powstaje z kodu. Stopa to sinus z opadającą wysokością plus krótki klik, werbel to trójkątny korpus z domieszką szumu, hi-haty i talerze to filtrowany szum, a głosy melodyczne pochodzą z własnego, niewielkiego subtraktywnego silnika syntezy z oscylatorami, filtrem i obwiedniami. To nie oszczędność, lecz pozycja prawna: w projekcie nie istnieje ani jeden obcy sampel, a parametry każdego dźwięku stoją w kodzie źródłowym.

7. Inferencja w przeglądarce

Środowiskiem uruchomieniowym jest TensorFlow.js 4.22.0, w całości hostowany samodzielnie - bez zależności od CDN, co zarazem odpowiada architekturze prywatności. Łańcuch backendów próbuje WASM, potem WebGL, potem CPU. Z liczb dotyczących latencji ten artykuł świadomie rezygnuje: nie przeprowadziliśmy systematycznej kampanii pomiarowej na różnych urządzeniach i przeglądarkach, a pojedyncze wartości z komputera deweloperskiego byłyby anegdotami. Kto chce własnych liczb, dostaje je z pierwszej ręki: wbudowany tryb benchmarku (wywołanie strony z ?bench=1) wykonuje 100 inferencji generowania i 100 inferencji wariacji ze stałym seedem i ujawnia backend, czas ładowania oraz p50/p95 jako JSON - zmierzone na własnym urządzeniu, nie na naszym.

Interesujące jest to, co przy tym rozmiarze modelu NIE jest problemem: czas inferencji i pamięć nie grają praktycznie żadnej roli. Właściwa praca inżynierska tkwi w otoczce: w procesach ładowania, fallbackach backendów i decyzji, by dostarczać środowisko uruchomieniowe razem z artefaktami modelu, zamiast pobierać je z menedżera pakietów.

8. Co AI robiła dobrze

Pierwsza działająca wersja aplikacji - sekwencer, synteza, mikser, patterny demo, strona z podstawowym wyposażeniem pod wyszukiwarki - powstała w jeden dzień roboczy, warstwa integracji TF.js tego samego wieczoru. Lookahead-scheduling był poprawny w pierwszym podejściu. Rejestr parametrów silnika syntezy generuje z jednego źródła regulatory, zakresy wartości, normalizację i dokumentację; bezklikowe obwiednie omijają znaną niekompatybilność przeglądarek (Firefox nie zna cancelAndHoldAtTime), obliczając analitycznie wartość krzywej w punkcie przejścia - rozwiązanie, którego w tej postaci nie znaleźliśmy w żadnym tutorialu.

I jeszcze jedno: AI konsekwentnie pisała testy do własnej logiki (na końcu 47), które wielokrotnie łapały prawdziwe błędy, zanim usłyszał je człowiek.

9. Gdzie AI zawiodła

Dziennik prac jest w tym miejscu najuczciwszym źródłem projektu.

Pusty ekran: pierwsza dostarczona wersja narzędzia do testów odsłuchowych pokazywała tylko nagłówek. Przyczyną był klasyczny błąd JavaScriptu (dostęp do stałej przed jej inicjalizacją), którego nie mógł zobaczyć żaden z 27 ówczesnych testów jednostkowych, bo żaden nie ładował punktu wejścia jako całości. Znalazł go człowiek na działającym systemie; konsekwencją była nowa klasa testów.

Gust muzyczny: pattern demo „Experimental” potrzebował dwóch podejść. Pierwsze było teoretycznie ciekawe (polirytmia, harmonika kwartowa) i - w ocenie człowieka - brzmiało po prostu okropnie. Drugie podejście stało się mrocznym groovem halftime i przeszło. Metryki na to nie było.

Użyteczność: znacznik otwartych hi-hatów był małą literą „o” i bywał czytany jako cyfra zero. Ścieżki melodyczne były początkowo celowo nieedytowalne, ale sprawiały wrażenie defektu. A układ nagłówków ścieżek potrzebował pięciu podejść, bo AI dwa razy z rzędu błędnie zinterpretowała polecenia - na końcu okazało się, że pierwotny układ był najlepszy, co uwidoczniło dopiero porównanie.

Uczciwość modelu: VAE systematycznie generuje za mało otwartych hi-hatów (występują tylko w 38,1 procent okien zbioru danych), a kwantyzacja do siatki szesnastkowej kosztuje 7,84 procent oryginalnych uderzeń (z rozszerzonym mapowaniem tomów drugiej wersji jeszcze 7,08), bo ludzka gra leży obok siatki (średnie odchylenie: 0,176 kroku). Obie rzeczy stoją także na stronie produktu, nie tylko tutaj.

Wierność gatunkowa: druga wersja modelu przyniosła bodaj najbardziej pouczający wynik projektu. Model POTRAFI grać tomy - rekonstrukcja patternów zbioru testowego osiąga, zależnie od klasy tomu, wartości F1 od 0,30 do 0,55, w rzędzie wielkości otwartych hi-hatów. Ale w generowanych patternach czterech stylów aplikacji tomy nie pojawiają się prawie wcale: na klasę tomu w 6,3, 1,3 i 7,5 procent przypadków. Powodem nie jest błąd treningu, lecz wybór kotwic: House, Electronic i Lo-Fi to dokładnie te gatunki, w których perkusiści prawie nie grają tomów - kotwice stylów leżą w ubogich w tomy regionach przestrzeni latentnej. Model odtwarza prawdę swoich gatunków, a nie życzenie swoich twórców.

Próba dowodowa nastąpiła dzień później i potwierdziła diagnozę. Piąta kotwica stylu „Fills”, obliczona jako średnia 6682 bogatych w tomy okien zbioru danych (około jedna trzecia danych, wszystkich dziesięciu perkusistów, co najmniej trzy uderzenia w tomy na dwa takty) - bez dotknięcia ani jednej wagi modelu: przy tej kotwicy tomy pojawiają się w 58, 20 i 61 procentach generowanych patternów zamiast w 6,3, 1,3 i 7,5, przy nienaruszonym zestawie podstawowym (stopa 92, werbel 95, zamknięty hi-hat 87 procent). Ceną jest ten sam mechanizm w przeciwnym kierunku: otwarte hi-haty spadają przy tej kotwicy do 5 procent, bo w prawdziwej grze wypełnienia zastępują właśnie pracę hi-hatu. Rozwiązanie nie polegało na zmianie modelu, lecz na pokazaniu mu innego regionu jego własnej mapy.

10. Rola człowieka

Według dziennika prac praca rozkłada się tak: AI napisała praktycznie cały kod i dokumentację. Człowiek podjął zasadnicze decyzje architektoniczne (własny model zamiast wytrenowanych checkpointów, gdy projekt Magenta okazał się zarchiwizowany), wszystkie oceny smaku i jakości (testy odsłuchowe, layout, patterny demo), strategię licencyjną i danych, i to on znajdował błędy, które widać dopiero na działającym systemie. Bez tych bramek aplikacja byłaby gotowa szybciej - i gorsza.

Jeden szczegół zasługuje na wzmiankę: podczas integracji człowiek raz wykonał commit w środku trwającej przebudowy; w commicie zabrakło dwóch nowych plików i build by się nie powiódł. AI rozpoznała wzorzec (udokumentowaną pułapkę procesu wdrożenia) i zgłosiła go, zanim pipeline zrobił się czerwony. Współpraca znaczy tutaj: obie strony łapią błędy tej drugiej.

11. Wynik

Aplikacja jest swobodnie dostępna pod adresem mybytes.com/mixer.html, bez konta i bez uploadu. Od czasu eksperymentu urosła: bank patternów z trybem utworu, subtraktywny silnik syntezy z 15 presetami i własnym edytorem brzmienia dla każdej ścieżki, formowalna synteza perkusji, arpeggiator i efekty send doszły w tych samych trybach pracy - AI buduje, człowiek decyduje.

12. Wnioski

Czy AI potrafi dziś zbudować kompletną aplikację webową? Potrafi zaskakująco dużo z tego zadania: w tym projekcie realizacja architektury, kod, testy i dokumentacja pochodzą niemal w całości ze środowiska AI, a tempo zasadniczo zmienia ekonomię takich eksperymentów - przebieg treningowy liczony w sekundach na CPU, jeden dzień roboczy do grywalnej aplikacji.

Czego nie zastąpiła: osądu. Każde miejsce, w którym produkt stał się dobry, a nie tylko funkcjonalny, było ludzką decyzją - od odrzuconej kotwicy stylu, przez dwa podejścia do patternu demo, po wniosek, że pierwszy layout był tym właściwym. Generatywna AI istotnie przesuwa tempo i podział pracy; odpowiedzialność za architekturę, kontrola jakości i gust pozostają pracą.

Transparentność: Model perkusyjny został wytrenowany na Groove MIDI Dataset (Google LLC, CC BY 4.0; Gillick, Roberts, Engel, Eck, Bamman: „Learning to Groove with Inverse Sequence Transformations”, ICML 2019). Wszystkie liczby w tym artykule pochodzą z dwóch udokumentowanych przebiegów treningowych (wersja 1: seed 20260809, wersja 2 z tomami: seed 20260810; identyczny podział zbioru danych) lub z pomiarów wymienionych w tekście; wartości pojedyncze są wartościami pojedynczymi, a nie średnimi z wielu przebiegów. Oba przebiegi odbyły się przed pierwszym commitem repozytorium treningowego; pliki metryk nie noszą dlatego referencji commita. Kotwica Fills to późniejsze uzupełnienie kotwic bez ponownego treningu; jej liczby obecności pochodzą z pomiaru na 100 wygenerowanych patternach (seed 20260811). Kod treningowy jest opublikowany jako repozytorium: github.com/myBytesResearch/drum-vae-mixer.

Źródła

  1. Internet Archive, Wayback Machine, migawki mybytes.com/mixer.html - najwcześniejsza: 16.02.2008, ostatnia: 16.03.2015; dostęp 2026-08-11.
  2. Komunikat prasowy Microsoftu, 13.02.2008: „Teens Less Likely to Download Illegally When They Know the Laws, Microsoft Survey Finds” (dostęp 2026-08-09).
  3. Blog YALSA (American Library Association), 26.02.2008: „MyBytes Teaches Teens a Little Something about Copyright” (dostęp 2026-08-09).
  4. Glen Rhodes, wpis portfolio MyBytes - glenrhodes.com/portfolio/portfolio/mybytes (dostęp 2026-08-09).
  5. Groove MIDI Dataset (Google LLC, CC BY 4.0; nagrany na zestawie e-drum Roland TD-11) - magenta.tensorflow.org/datasets/groove (dostęp 2026-08-11). Publikacja: Gillick, Roberts, Engel, Eck, Bamman: „Learning to Groove with Inverse Sequence Transformations”, ICML 2019.
  6. Projekt Magenta, zarchiwizowany w styczniu 2026 - github.com/magenta/magenta (dostęp 2026-08-09).
  7. Chris Wilson: „A Tale of Two Clocks” (lookahead scheduling dla Web Audio) - web.dev/articles/audio-scheduling (dostęp 2026-08-11).
  8. Wsparcie przeglądarek dla AudioParam.cancelAndHoldAtTime - caniuse.com/mdn-api_audioparam_cancelandholdattime (Firefox bez wsparcia; stan na 2026-08-11).
  9. Repozytorium treningowe ze wszystkimi danymi pomiarowymi, seedami i notebookiem wyników - github.com/myBytesResearch/drum-vae-mixer.
Repozytorium towarzyszące: github.com/myBytesResearch/drum-vae-mixer - kod treningowy, dane pomiarowe, seedy i notebook wyników; wszystkie liczby tego artykułu odtwarzalne z udokumentowanych przebiegów.