История за загубата и любовта към иновациите

Подкаст

Наскоро бях помолен от Gant Laborde да бъда в предстоящ подкаст и аз, след като не знаех какво да предложа за дискусионни точки, започнах да разсъждавам върху част от работата с отворен код, която правех... предложих като тема на дискусия за подкаста: „Ами ако машинното обучение беше достатъчно просто за деца? Пътуване в осъществяването му.”, и когато започнах да пиша, стана ясно, че тази история трябва да бъде споделена.

Единствената причина, поради която мога да разбера, че Гант би ме поканил като гост на подкаста, е работата, която съм положил за няколко GPGPU и софтуерни библиотеки за машинно обучение (подкастът е за машинно обучение) и може би собствената ми упорита воля да отхвърли идеята, че настоящите библиотеки за машинно обучение, по-специално невронните мрежи, са лесни за използване и лесни за разбиране. Те просто не са и е пълен боклук, ако някой ви каже това, или поне… мога да кажа, че така беше.

Позволете ми да започна с разяснение на темата, която предложих за подкаста: нямам предвид библиотеки за машинно обучение върху библиотеките за машинно обучение, върху машинното обучение библиотеки, които ги правят по-лесни за използване, така че детето да може да ги използва. Това, което имам предвид, е следното: ами ако бяха приложени по начин, по който дете (ще кажем над 10 години, с основни познания за умножение, деление, изваждане, събиране и леко програмиране) може да разбере гайките и болтовете зад API, с които го изграждаме?

  • В началото: ползата е, че дете, възрастен или професионалист всички могат да ги разберат. Сладка! Това е страхотно.
  • Но навлизайки по-дълбоко: Ами ако заради тях, мили милостиви farfegnugen, някой {драматична пауза тук, след което каза бавно} иновира

Държавата

Текущото състояние на начина, по който се изграждат повечето сериозни библиотеки за машинно обучение, като цяло е толкова много близко до метала. И с основателна причина… за представяне. Поради това получаваме API, за който някой другаде се е сетил, и ни е наредено да го използваме по много специфичен начин. „Металът“ тук е като c++, glsl, opengl, vulkan, metal, разбирате идеята.

На ниво бизнес логика ние просто трябва (казахме) да приемем тези API. Докато тези библиотеки са изложени на език от по-високо ниво, като python или (да, ще го кажа!) javascript (или typescript), има толкова много нива на абстракция, че за да се постигне предложена тема за подкаст става толкова много трудно за някой да прави иновации или дори просто да има основно разбиране за това как работи всичко, поради екстремната крива на учене.

Но не трябва да е така...

Смелостта

Ами ако езикът от по-високо ниво като javascript съставиезика от по-ниско ниво като c++, директно,И изпълнихте ли го там, където беше най-ефективен? Това е голямата идея, революцията, върху която работя повече от 3 години, с много успехи. Но това не е моя идея, аз просто видях блясък на тази визия и реших да я прокарам напред.

Кой би посмял да излезе с такава идея?

Оказва се, че няколко приятели в Сингапур и в крайна сметка го построиха...

След 24 часа…

„На хак-а-тон…“

И спечелиха второ място.

Ще се върна към тази история.

Търсенето

Някъде преди около четири години започнах търсене. Знам javascript и исках библиотека за машинно обучение със сериозна производителност, написана на javascript. Лесно нали? Моето алчно егоистично желание беше да мога да го разбера и да го използвам. Графиките в Wikipedia бяха доста ясни и аз се запознах с тях през годините:

Търсих в мрежата часове, след това дни, след това седмици (не непрекъснато) и открих няколко библиотеки, които имаха фантастични API, НО те по същество бяха смятани за „играчки“. Разглеждайки по-подробно защо, открих, че те просто не могат да се справят с производителността, необходима в сериозни, напрегнати приложения с ГОЛЕМИ ДАННИ.

В един момент започнах да говоря с общност от разработчици, които използваха най-често срещаните набори от инструменти, за да ги проектират обратно за javascript. Няма да споменавам коя общност. Но веднага щом се разбра, че се опитвам да подобря javascript, ми казаха заглавието на тази история:

Вземете истински език.

Загубата

Това ме нарани, тъй като си спомням дните на изоставяне на C# в полза на javascript, защото нямаше време за компилиране, забележимо от хората. Как можете да изберете да направите нещата силно въведени, въпреки че езикът е слабо въведен. Простотата, елегантността, иновацията. Как се превърна в моето основно средство за програмиране за повече от 10 години. Как общността с отворен код javascript, макар и несъвършен, като цяло е много полезен.

Javascript е фантастично бърз за това, което е, базиран на процесора език на високо ниво. Така че, когато обработвате графика (снимки, видео и ние ще добавим тук „големи количества данни“), използвайки го, обработващият модул, на който той обикновено работи, се облага сериозно и производителността е едно от първите неща, които трябва да излязат. Има начини за облекчаване на това, като например многопоточност, но количеството режийни разходи, за да се възползвате от множество нишки, макар и по-бързо (технически не е по-бързо, те обработват със същата скорост, но работното натоварване се разделя и изпълнява в тандем, който създава илюзията, че е по-бърз), не променя архитектурното ограничение. Процесорът е проектиран да прави едно. нещо. при. а. време.

Има друга архитектура, която е проектирана за масивна едновременност. Графичният процесор… „GPU“. Защо е по-добре при едновременност? Нека оставим Разрушителите на митове да обяснят, че:

Беше някъде в този депресиращ момент, случайно се върнах (бях го виждал няколко пъти) на Brain.js. Когато прелистих изходния код този път, аз (както много други) почувствах, че има API от световна класа, беше абсурдно лесен за разбиране и беше изключително популярен (за javascript)… И тогава прочетох, че това е изоставен.

Шокиран, отидох на страницата с проблеми, за да видя дали има нещо, което се прави по въпроса. Имаше само проблеми и въпрос защо беше изоставен.

Вместо да навлизаме в тази история защо, ще се съсредоточим върху тази… Не съм сигурен дали беше шокът или депресията, но започнах да имам идея, че просто защото библиотеката каза беше изоставен и все още нямаше възможности на GPU... че може и аз мога да бъда този, който ще го направи или поне ще помогне ;) . Можех да се погрижа за това, да продължа работата на библиотеката, да продължа нейната история...

Но как някога ще работи Brain.js на графичния процесор и ще бъде съставен от javascript? Това беше второто търсене, търсенето, което ме доведе до дива идея за иновации. Идеята „не е моята идея“.

Отговорът

Ако можех да изградя (или подобря) среда, която:

  1. изчисли изходния код на ниско ниво, необходим за работа на GPU
  2. позволи ми да пиша в чист javascript (или машинен скрипт)
  3. който имаше сериозна производителност на GPU

Тогава щях да правя нещо съвсем ново и широко необходимо. Тогава бихме могли да внедрим иновации в javascript за този тип проблеми, защото може да бъде широко разбран. Важно е да споменем, че това не се отнася само за приложенията за машинно обучение, а по-скоро за нова парадигма на програмиране, която позволява на човек с почти никакъв опит да пише фантастично сложен софтуер, който се възползва напълно от хардуера , като пример е устройството, с което четете това.

Имаше проблем, 24-часовият hack-a-thon проект, GPU.js, наистина беше просто доказателство за концепцията, целият му набор от функции не беше добре тестван или документиран и въпреки че създателите му свършиха добра работа с него , все още беше… бъги. Беше в много подобно състояние на Brain.js и дори не работеше на Node.js. Така че за мен това беше сделка 2 за 1. Продължете с Brian.js И GPU.js, направете го да работи на Node.js и едва тогава ще имаме сериозно бърз javascript за машинно обучение.

Въоръжен с тази идея, виждах как се изправям срещу този отрицателен отговор „Вземете истински език“, използвам го като гориво, като мотивация и научавам много между тях. На което най-накрая можех да отговоря лекомислено:

„Вземете истински език? Направих. И неговият Javascript.

Но с какво този подход е различен?

Човек може да зададе горния въпрос и всъщност го направих на себе си (и все още го правя), преди най-накрая да започна. Лесно е да не разберете защо стратегията, която Brain.js би предприел, би била толкова различна, така че бързо ще обясня и обобщя, защото е важно.

Ще изберем библиотека, която не съществуваше тогава, но съществува сега: Tensorflow.js, фино написана библиотека за машинно обучение, която имитира донякъде педантичния API от Tensorflow. Въпреки че Tensorflow.js има някои javascript, той също така съдържа отделно написани и поддържани WebGL (и скоро ще бъде WebGPU) двойници И обвързвания на възли И c++ еквивалент. Това е важно: Тези среди и обвързвания идват с технически дълг. Така че за всяко едно от всичко има поне... три(или повече, четири, пет?) части, които трябва да се поддържат.

Недостатъкът на това е, че може да доведе до различно поведение в околната среда, да, но нека отидем по-дълбоко. Представете си, че съм достигнал границата на това, което Tensorflow.js може да направи, и имам нова математическа интуиция, или тип слой, или активиране, което искам да опитам, нали? Е, не мога да го напиша веднъж и да го забравя. Трябва да го напиша веднъж (c++) и след това да го изложа като свързване на Node.js и след това да го напиша отново(javascript) и отново(WebGL), (и накрая отново,WebGPU)… Това е обратното на простото.

Представете си, че пишете роман по същия начин, или рисувате, или оцветявате, или... разбирате идеята. Не се опитвам да атакувам Tensorflow.js, просто казвам този подход, докато Tensorflow.js върши страхотна работа, като кара javascript/typescript да има средство за машинно обучение, писането толкова конкретно, с целия този потенциален технически дълг към всяка среда не е иновативно. Чувствам се много силно за това. Това е/беше „статуквото“. Така може да се каже, че много голяма част от тази самата библиотека за машинно обучение, въпреки че е добре написана и подкрепена от компания, която е не е зла, НЕ е напълно javascript/typescript.

Сега хипотетичният подход, който си представих като GPU.js и Brain.js: Докато GPU.js (GPGPU библиотека) ще трябва да бъде написан, за да се възползва от повече от една среда (или бекенд) като: WebGL1, WebGL2, HeadlessGL и Javascript, всяко от тези са цели, към които бихме компилирали входния източник на javascript. Това е много важно. Тогава вътрешността на GPU.js би била много обща. Това би било умишлено. Поради това бихме могли да тестваме общото поведение по-подробно. Като ifизявление или for цикъл, или прецизност.

Brain.js, от друга страна (Библиотека за машинно обучение), е написан само на javascript. Да, най-разпространеният език за програмиране на планетата. Един език, един API, прост и ясен. Това би бил барът. Изискването да го продължите. Javascript ще бъде използван като средство за композиране, за генериране на източника за другите бекендове и още бекендове като: WebGPU, Vulkan и ArrayFire.js могат да бъдат добавени по всяко време. Brain.js ще трябва само да инсталира по-новата версия на GPU.js, както и всички зависимости, за да получи тази нова среда.

От любовта към иновациите

Това беше начинание, което в крайна сметка щеше да отнеме години, но си заслужаваше и си е струвало.

Защо си струва? Когато човек прави иновации, иновациите предизвикват експлозия, експлозия на иновации.

Ето един пример:

Използването на електричество е друг пример.

Твърди се, че машинното обучение е „следващото електричество“.

Програмирането на GPU е (или е било) изключително трудно (вероятно) за работа отчасти поради:

  • лошо написани драйвери
  • лошо написани реализации
  • да бъдеш зле разбран
  • много бързо подобряване на API за отстраняване на тези предишни недостатъци

Но ако можехме да пишем на един, широко разбираем, много изразителен, много ясен език, като оскъден javascript, който компилира надолудо езиците от по-ниско ниво, тогава бихме могли движеща се цел на компилатор. С други думи, можем да компилираме в реално време до най-добрия език И среда на устройството, на което сме.

Това всъщност не е нова идея, някои примери са c++, python, typescript и дори javascript. Тези (почти всички) езици или се интерпретират, или се компилират до нещо по-ниско ниво и по отношение споделят тази идея, но не по радикалния начин на език от такова високо ниво като Javascriptсамият съставяне на език от такова ниско ниво като c++ (или подмножество на c++, glsl) на толкова различна процесорна единица като GPU.

Зает съм

След стотици човекочасове, повече от три години работа — около това да бъда съпруг, баща и моя ежедневна работа — GPU.js v2 -“Cosmic Jellyfish” беше пуснат миналия месец по време на писането на тази история. GPU.js ви позволява да пишете с много прост javascript, който се транспилира в GPU. Може да се изпълнява в браузъра (Linux, Window, OSX, iOS и Android) чрез WebGL1 & WebGL2, на сървъра (Node.js) чрез HeadlessGL и дори в собствени приложения (Expo) чрез @gpujs/expo -gl.

Бързо напред и с Brian.js, общността в крайна сметка се намеси, за да помогне за подобряването му, да продължи наследството му и за мен беше чест в крайна сметка да стана водещ разработчик. Оттогава до сега работя с много други, които споделят подобно желание. Добавихме нови типове невронни мрежи, като повтаряща се и времева стъпка, подобрихме инструментите, като кръстосано валидиране, надградихме съществуващия API, така че да имате опциите да използвате GPU на някои места, чрез GPU.js и сме във финала етапи на завършване на конволюция, мрежова композиция и повтарящи се GPU реализации за V2 на Brain.js. „Дори имахме алфа версия миналия месец.“

Въпреки това имаше някои доста значителни забавяния по пътя, започващи около декември миналата година, главно поради скучни неща като:

  • в GPU.js масивно пренаписване, за да се отчете изводът за тип от край до край (да, силни типове в javascript! НЕ typescript) — поради грешки в Node.js
  • писане на единични тестове (сега над 20 000+ твърдения) и коригиране на грешки — необходими за доказване на проектите и идеите зад тях
  • добавяне на способността за GPU ядрата да се „самопрекомпилират“, при смесване на тръбопроводен режим — за ефективност и стабилност при търсене на индекс на масив
  • добавяне на Node.js поддръжка чрез HeadlessGL, подобряването му и добавянето му като сътрудник
  • Много дълъг списък от други неща, използвани за използване и по-пълноценно използване на GPU

Поглеждайки назад

Мога да кажа, че научих повече, бях тласкан повече и преодолях повече препятствия през последните три години, и по-конкретно през последната една година, отколкото когато и да било. От. Далечната. И въпреки че има много хора, които са помогнали по пътя, голяма част от това да стигнем дотук е благодарение на двама души:

  1. Gante Laborde: благодаря ви, че ме насърчихте и бяхте толкова безгрижен и професионалист по отношение на технологиите и машинното обучение и ме поканихте да участвам в подкаст
  2. Човекът, който ми каза „вземи истински език“, защото сега мога да кажа:

„Направих го и това е Javascript.“

Движа се напред

Въпреки че нещата понякога изглеждат бавни, ние не сме спрели. Подготвяме се да пуснем нов дизайн на уебсайт за GPU.js и се свързахме с помощта на Jay Weeks, Michelle Bowser и Harsh Khandeparkar (благодарим, момчета!) и съвсем наскоро внедрихме друг редизайн на уебсайта за Brain.js, благодаря на Muhammad Ubaid Raza и най-накрая мога да пусна Brain.js v2, вместо просто да продължавам да говоря за него!

Работата обаче продължава и ние все още внимателно добавяме нови функции, когато е необходимо. Но преди да бързаме да внедрим нещо ново, ние си задаваме въпроса: „Достатъчно прост ли е API за дете?“… Ако е твърде сложен, опростяваме и питаме отново. След това от време на време спираме и си мислим: „Ние правим нещо, което е далеч по-различно от правеното, и то започва да се развива и помага на хората... да правят иновации“.

Сега това е истински език.

Заключителни бележки

Отрицателната енергия не е нещо лошо, тя може да ни помогне да се съсредоточим върху трудни задачи или да ни даде енергия за преодоляване на големи препятствия. Искрено се надявам тази история да не носи негативна енергия, а само положителна. Ще има хора, които ще ти кажат „не можеш да направиш това!“, на което съм отговарял много пъти „Вече съм го направил“. Но ако задачата си заслужава изпълнението и все още не е изпълнена, докажете го на себе си и НЕ СЕ ПРЕДАВАЙТЕ!

В софтуерното инженерство „истинският език“ не трябва да бъде само един или два от тях, трябва да бъдат всичките. Но ние знаем реалността, че един може да има по-добри инструменти от друг, това е просто естеството на подобряването на софтуера. Ако обаче установите, че поставяте под съмнение статуквото, виждате по-добър, по-прост начин за правене на нещата и срещате съпротива, може да сте на път за нещо.

Поставете под въпрос идеята си, докажете я, тествайте я, планирайте я. Ако издържи, отпразнувайте това и след това, разбира се, заемете се с нововъведения.