Skúmanie možností umelej inteligencie koncom roka 2021 ma previedlo cez mnohé obručky. Sú veci, ktoré už fungujú, sú veci, ktoré možno optimalizovať pre lepší výkon a potom sú veci, ktoré zdanlivo nefungujú vôbec.

Jednou z takých vecí je inštalácia caffe. Nie je to vaša priemerná každodenná káva, ani hashtag #caffe, ktorý možno nájsť plávať po sociálnych sieťach. Nie, toto CAFFE je Convolutional Architecture for Fast Feature Embedding. Aktuálna definícia na domovskej stránke uvádza nasledovné:

Caffe is a deep learning framework made with expression, speed, and modularity in mind. It is developed by Berkeley AI Research (BAIR) and by community contributors. Yangqing Jia created the project during his PhD at UC Berkeley. Caffe is released under the BSD 2-Clause license.

Je to teda komunitou udržiavaný open-source projekt, dosť dobre prijatý v príslušnom svete, keďže prináša niektoré jedinečné výhody do hlbokého učenia, nie nevyhnutne prítomné u ostatných konkurentov.

AUR a caffe #

Oficiálny repozitár na GitHub je BVLC/caffe, ale v čase písania bol posledný skutočný commit kódu do vetvy master #99bd9979 dňa 21. aug 2018.

Caffe z tohto repozitára je dostupné v aur/caffe a aur/caffe-git. Ich PKGBUILDs nemajú absolútne žiadny rozdiel. Verte mi, dôkladne som to skontroloval. Môžete si urobiť diff sami porovnaním PKGBUILDs caffe a caffe-git (odkazy sú na snímky z času písania).

Jediný rozdiel je commit zdrojového kódu, čo je samozrejme norma v AUR. Ak nie ste oboznámení s konvenciami tam, funguje to takto: balíček caffe z AUR je viazaný na konkrétne vydanie. V čase písania je to 1.0, keďže zdrojový blob je vydaný spolu so skutočným vydaním. Na druhej strane, caffe-git (alebo všeobecne akýkoľvek balíček končiaci -git) používa najnovší commit z predvolenej vetvy, zvyčajne master. A je tam 136 commitov rozdiel, ovplyvňujúci 100 súborov, čo možno vidieť v tomto diffe, opäť so snímkou z času písania.

V AUR je veľa ďalších verzií caffe, ale vynechávam ich, pretože všetky cielene na nejaký konkrétny GPU hardvér, ako nVidia CUDA. Zameriam sa len na CPU verziu caffe. Pre mňa git verzia zostavuje a funguje pekne, ale vydaná verzia nie. Chyba, ktorá zastaví proces zostavenia pre vydanú caffe končí nasledovným:

CXX tools/extract_features.cpp
CXX/LD -o .build_release/tools/extract_features.bin
/usr/bin/ld: .build_release/tools/extract_features.o: in function `int feature_extraction_pipeline<float>(int, char**)':
extract_features.cpp:(.text._Z27feature_extraction_pipelineIfEiiPPc[_Z27feature_extraction_pipelineIfEiiPPc]+0x37c): undefined reference to `caffe::Net<float>::CopyTrainedLayersFrom(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
collect2: error: ld returned 1 exit status
make: *** [Makefile:638: .build_release/tools/extract_features.bin] Error 1
make: Leaving directory '/home/peterbabic/.cache/yay/caffe/src/caffe-1.0'

Po veľa experimentovaní (čítajte nižšie) táto chyba nakoniec zmizla a bol som tiež schopný zostaviť túto vydanú verziu testujúc spätne, takže pravdepodobne som časom správne nastavil niektoré závislosti OpenCV, ale neviem presne určiť, čo sa zmenilo, hoci by to mohlo byť užitočné. Každopádne, toto je v podstate najmenej funkciami bohatá verzia caffe zo všetkých skúmaných, takže to nie je taká veľká záležitosť.

Miešanie caffe vidličkou #

Ako som pred chvíľou povedal, oficiálna verzia caffe zdá sa, že už nie je udržiavaná. Ale to neznamená, že skutočná potreba zlepšení zmizla. V rozvetví caffe vo vetve ssd repozitára weiliu89/caffe prebieha významný vývoj. A SSD tu vôbec neznamená úložisko. Namiesto toho SSD tu znamená Single Shot Detector, alebo presnejšie Single Shot MultiBox Detector. SSD bolo vyvinuté na zníženie výpočtových zdrojov potrebných, aby model mohol bežať na vstavaných zariadeniach, ako sú autonómne vozidlá. Primárny autor SSD, Wei Liu, začal rozvetvenie počas svojej stáže v Googli a vyzerá to, že zanechal vo svete stopu.

Chcel som použiť SSD rozvetvenie caffe na nejaké experimentovanie, ale nech som skúšal čokoľvek, nedokázal som nájsť spôsob, ako ho zostaviť. Chyby vyzerali takto:

In file included from /usr/include/c++/11.1.0/ext/string_conversions.h:41,
                 from /usr/include/c++/11.1.0/bits/basic_string.h:6594,
                 from /usr/include/c++/11.1.0/string:55,
                 from ./include/caffe/util/hdf5.hpp:4,
                 from src/caffe/util/hdf5.cpp:1:
/usr/include/c++/11.1.0/cstdlib:75:15: fatal error: stdlib.h: No such file or directory    hpp:
   75 | #include_next <stdlib.h>
      |               ^~~~~~~~~~
compilation terminated.
make: *** [Makefile:580: .build_release/src/caffe/util/hdf5.o] Error 1

Vyššie uvedená chyba zdanlivo súvisí s parametrom -isystem oproti prostému -I v procese zostavenia. Tu možno nájsť niektoré relevantné referencie tu, tu a následne tu, potom tu, tu a dokonca tu, ale zoznam by mohol pokračovať dlho.

Po vyriešení vyššie uvedeného problému sa objavil ďalší:

src/caffe/util/im_transforms.cpp:2:10: fatal error: opencv2/highgui/highgui.hpp: No such file or directory
    2 | #include <opencv2/highgui/highgui.hpp>
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make: *** [Makefile:580: .build_release/src/caffe/util/im_transforms.o] Error 1

A úzko súvisiaci tiež, len skrátený:

src/caffe/util/io.cpp:13:10: fatal error: opencv2/core/core.hpp: No such file or directory

Toto bolo ďalej vyriešené ladením INCLUDE_DIRS, ako bolo naznačené tu, tu a tu. Myslím, že v tomto bode som bol schopný zostaviť caffe pomocou make.

Poznámka k Cmake a OpenCV 4 #

Avšak predtým, ako som sa mohol vzdať make, pre ktoré sú funkčné PKGBUILDs ľahko dostupné v AUR, ako je diskutované vyššie, bol som schopný spustiť komunitou podporované Cmake zostavenie. Ale nie skôr, ako som prekonával problémy ako:

CAP_PROP_POS_FRAMES was not declared in this scope.

Ďalšie podrobnosti možno nájsť tu. Najprv bolo potrebné nejaké záplatovanie, vysvetlené tu, tu, potom tu a veľmi stručne tu.

Viem, že Cmake zostavenie a OpenCV 4 nie sú prepojené, ale presné chybové správy som si nezaznačil, aby som ich tu uviedol ako referenciu. Aplikované záplaty jednoducho fungujú pre make aj Cmake zostavenia rovnako a Arch má OpenCV 4 v repozitároch už dosť dlho, takže som ich dal dokopy.

Hoci som bol schopný zostaviť Cmake skôr, oficiálne make zostavenie je oveľa prehľadnejšie organizované a kompiluje všetko, čo caffe ponúka vrátane dokumentácie a všetko toto je využívané v PKGBUILD, zatiaľ čo Cmake len zostavuje binárky, takže som sa rozhodol ďalej nevyužívať cestu Cmake.

Poznámka k atlas-lapack a NumPy #

Existuje zamotaný svet matematických knižníc nesúcich názvy BLAS, Atlas, lapack, lapacke, OpenBLAS a Intel MKL. Funkcie, ktoré ponúkajú, sa do určitej miery prekrývajú a v mnohých linuxových distribúciách si môže používateľ zvoliť, ktorú implementáciu použiť. Táto situácia na Archu sa zdá byť nie príliš skvelá.

Napríklad, caffe štandardne očakáva implementáciu Atlas, ale dostať sa k nej na Archu je veľmi ťažké, alebo možno dokonca v tejto chvíli nemožné, keďže sa mi to vôbec nepodarilo. Atlas je dostupný len z AUR ako balíček atlas-lapack a je to totálna bolesť nainštalovať ho. Nehovoriac o tom, že samotné zostavenie trvalo väčšiu časť dňa na mojom zariadení, keď som ho vôbec dokázal spustiť. Vôbec neodporúčam vydávať sa touto cestou!

Dôvod je ten, že ostatné Python balíčky prestanú s touto implementáciou fungovať:

ImportError: libopenblas.so.3: cannot open shared object file: No such file or directory

Nie som si príliš istý presným vzťahom k NumPy, pretože som bol v tomto kroku ešte pred tým, ako som spustil Cmake zostavenie, ale verím, že tam bola nejaká súvislosť. Ďalšia chyba, na ktorú som narazil, bola:

Could NOT find NumPy (missing:  NUMPY_INCLUDE_DIR NUMPY_VERSION) (Required is at least version "1.7.1")

Problémy, ktoré som mal počas tejto fázy, sú diskutované tu a tu. Záver je vyhnúť sa používaniu implementácie Atlas, keďže OpenBLAS je overene funkčné. Poznamenajme, že som vôbec neexperimentoval s Intel MKL, ale je to tretí uchádzač v tejto oblasti podporovaný caffe.

Poznámka k draw_net.py #

Tu sa dostávame k jadru tohto nie príliš zaujímavého príbehu. Dôvod, prečo som chcel, aby fungovala SSD verzia caffe, bol vlastne s ňou dodávaný súvisiaci skript draw_net.py slúžiaci na vizualizáciu caffe modelu špecifikovaného v súbore .prototxt. Takáto vizualizácia uľahčuje pochopenie toho, čo sa vo vnútri modelu deje. Tento skript je dostupný aj vo vanilla caffe, ale pri aplikácii na SSD model ako Mobilenet-SSD sa ukončí s chybou:

google.protobuf.text_format.ParseError: 1177:3 : Message type "caffe.LayerParameter" has no field named "permute_param".

Riešením je zjavne rozšíriť parametre, ktoré skript draw_net.py dokáže spracovať, o parametre používané v SSD modeli na prvom mieste, teda nainštalovať vetvu SSD caffe. Ukázalo sa to byť exponenciálne komplikovanejšie, ako som predtým predpokladal (trvalo mi to takmer týždeň). Avšak, dokonca aj po úspešnom zostavení vetvy SSD, draw_net.py stále zobrazoval chybu:

AttributeError: 'google.protobuf.pyext._message.RepeatedScalarConta' object has no attribute '_values'

Riešením je záplatovať zdrojový súbor draw.py, ako je opísané tu. Teraz som konečne bol schopný plne vizualizovať model. Aká jazda.

Balíček caffe-ssd je teraz dostupný v AUR.

Odkazy #