Bruk av åpen kildekode-biblioteker for nevrale nettverk i C++

Bruk av åpen kildekode-biblioteker for nevrale nettverk i C++

Bruk av åpen kildekode-biblioteker for nevrale nettverk i C++

Introduksjon

Moderne AI kommer ofte inn i et selskap gjennom Python, notatbøker, demomiljøer og den forståelige spenningen ved å se en modell fungere for første gang. Den fasen er ekte, nyttig og til og med litt magisk. Det er her nysgjerrighet er billig og iterasjonen er rask. Men livet til et ekte produkt slutter ikke ved demoen. En modell som må betjene kunder, passe inn i en backend, kjøre på fabrikkmaskinvare, leve i et skrivebordsprodukt eller overleve dårlige nettverksforhold er ikke lenger bare en modell. Det blir en komponent i et system, og systemer er der ingeniørmodenhet begynner å ha betydning.

Det er øyeblikket da C++ kommer tilbake til rommet. Produksjon stiller spørsmål som eksperimentering på høyere nivå bare kan utsette så lenge. Hvor mye minne trenger egentlig prosessen? Hva er steady-state latens under belastning? Kan oppstartstid overleve autoskalering? Kan kjøretiden leve i en eksisterende innebygd applikasjon? Kan vi sende den samme slutningsbanen til en server, en kantboks og en operatørarbeidsstasjon uten å bygge om hele produktet rundt en forskningsstabel?

Åpen kildekode-biblioteker er det som gjør denne overgangen mulig uten å overgi kontrollen til en leverandørs svarte boks. De gir oss stabile kjøretider, tensorabstraksjoner, optimaliserte kjerner, kvantiserte utførelsesbaner, maskinvarebevisste backends, og i den nylige LLM-æra, overraskende dyktige lokale inferensmotorer. Men overfloden av bibliotek kan også gjøre landskapet forvirrende. Ingeniører spør ofte hvilket bibliotek som er best når det beste spørsmålet er hvilket bibliotek som er ærlig om jobben foran oss.

Denne artikkelen tar den mer jordete veien. Vi vil se på de viktigste C++-relevante bibliotekene i AI som ingeniørpersonligheter med styrker, blindsoner og driftsforutsetninger. Mot slutten er målet å forstå når ONNX Runtime, LibTorch, oneDNN, OpenVINO, TensorFlow Lite, og llama.cpp hjelper, når hver og en blir for tung, når hver enkelt blir for smalt, og hvordan man velger moten uten å bli presset.

Hvorfor AI-systemer fortsetter å gå tilbake til C++

Det er en rytme til AI levering som er verdt å nevne tydelig, for når du først ser det, blir mange arkitekturvalg lettere å forstå. Først er det oppdagelsesstadiet. Forskere og produktingeniører lærer fortsatt hva modellen kan gjøre, hvilke data den trenger, og hvor verdien faktisk kan ligge. På det stadiet slår uttrykksevne disiplin. Rask eksperimentering, rikt Python verktøy og fleksible forskningsrammer er akkurat det teamet trenger.

Så kommer det mindre glamorøse andre stadiet, hvor en prototype begynner å samle forpliktelser. Et støtteteam må forstå feil. Et SRE-team ønsker forutsigbar oppstart og minneadferd. Finans ønsker å vite om serveringsregningen er en midlertidig topp eller en permanent lekkasje. En innebygd kunde spør om modellen kan kjøre offline. En sikkerhetsgjennomgang spør hva som eksakt sendes inne i binæren og hvilke deler som kan revideres. Plutselig slutter modellen å være en forskningsartefakt og blir en borger i et produksjonsmiljø.

C++ kommer stadig tilbake på det tidspunktet fordi det lar ingeniører svare på konkrete spørsmål i stedet for å vifte rundt dem. En innebygd tjeneste kan kontrollere allokeringsstrategier, trådpooler, ABI-grenser, pakking, CPU-spesifikke optimaliseringer og integrasjon med eksisterende ytelsessensitive undersystemer. Den kontrollen betyr mest der det er nødvendig, og der er det veldig vanskelig å fake med retorikk.

Et nyttig moteksempel hjelper her. Hvis teamet ditt bygger en lett lastet intern dokumentklassifisering som kjører én gang i timen, kan banen til minste motstand være en Python-tjeneste med et stabilt serveringsrammeverk og svært lite innfødt kode. Det er ikke noe skammelig med det. På den annen side, hvis det samme teamet legger inn slutninger i en ventetid-sensitiv C++ desktop-applikasjon, sender til en edge-enhet med begrensede ressurser, eller setter inn modellkjøring direkte i en hot backend-bane, blir det veldig raskt dyrt å late som om kjøretidsspråket ikke spiller noen rolle. Med andre ord, C++ er fortsatt et av de mest seriøse svarene når systemet selv blir problemet.

Bibliotekene som ingeniørpersonligheter

Den enkleste måten å gå seg vill i dette økosystemet er å behandle hvert bibliotek som om det konkurrerer om den samme jobben. Det er de ikke. Et treningsorientert rammeverk, en bærbar inferenskjøring, et kjernebibliotek og en lokal LLM-motor løser alle forskjellige problemer. Hvis vi kollapser dem i én kategori kalt AI-biblioteker, ender vi opp med å ta valg basert på merkekjennskap i stedet for systemdesign.

ONNX Runtime er, i mange produksjonsmiljøer, det mest disiplinerte og minst teatralske valget. Den er bygget rundt et rent løfte: eksporter modellen til et stabilt format, last den gjennom en kjøretid som fokuserer på utførelse, og la applikasjonen eie resten av systemet. Det høres enkelt ut, og enkelhet er nettopp derfor den er kraftig. ONNX Runtime er ofte det riktige svaret når forskningsfasen allerede har skjedd andre steder, og det som gjenstår er det nøkterne arbeidet med å betjene inferens gjentatte ganger, bærbart og med forutsigbar operasjonell atferd. En datasyn-backend som mottar bilder, normaliserer tensorer, kjører en kjent graf og returnerer resultater til en eksisterende C++-tjeneste er en ideell ONNX Runtime-historie. En dårlig passform vil være et produkt hvis kjerneverdi avhenger av dynamisk treningstidsadferd, hyppig grafoperasjon inne i applikasjonen, eller et stadig skiftende sett med tilpassede operatører som gjør eksporten sprø. I et slikt tilfelle kan kjøretidsgrensen som så ren ut til å begynne med bli en kilde til friksjon.

LibTorch har en annen karakter. Det er ikke først og fremst en lett utførelsesgrense. Det er C++ ansiktet til et fullstendig dyplæringsrammeverk. Det gjør det tyngre, men det gjør det også mer uttrykksfullt. Når en innebygd applikasjon virkelig trenger tensor-eierskap, modellkonstruksjon, treningslignende manipulasjoner eller nær PyTorch-semantikk på tvers av utvikling og produksjon, blir LibTorch mer overbevisende enn ONNX Runtime. Det er en viss ærlighet i å velge det når produktet virkelig trenger et rammeverk i stedet for en kjøretidsgrense. Moteksemplet er like viktig. Noen ganger bruker team LibTorch for enkel statisk slutning fordi det føles prestisjefylt eller fremtidssikkert. Så oppdager de at de importerte en mye større konseptuell og operasjonell overflate enn arbeidsmengden krevde. En liten slutningstjeneste som bare trengte å laste en stabil modellgraf kan betale for den avgjørelsen i pakkestørrelse, kompleksitet og feilsøking.

oneDNN og OpenVINO lever nærmere metallet og belønner en mer prestasjonsbevisst tankegang. oneDNN er biblioteket du setter pris på når CPU-kjerner, minneformater og effektivitet på operatørnivå blir viktig nok til å fortjene direkte oppmerksomhet. Mange lag bruker det indirekte gjennom kjøretider på høyere nivå, noe som ofte er lurt. OpenVINO, i mellomtiden, sitter på et mer strategisk sted. Det hjelper team som bryr seg om Intel-orientert distribusjon, grafoptimalisering og maskinvarebevisst utførelse uten å ønske å manuelt administrere hver enkelt detalj på lavt nivå. I praksis begynner disse verktøyene å ha betydning når forretningsproblemet ikke lenger bare er "kjør modellen", men "kjør modellen effektivt på maskinvaren vi faktisk kan kjøpe, distribuere og vedlikeholde." Det skillet høres lite ut i et møte og blir veldig stort i et budsjett.

TensorFlow Lite representerer et helt annet temperament. Det er tilbakeholdenhetens stemme. På edge-enheter, mobile mål og ressursbegrensede systemer er fullstendighet ofte mindre verdifullt enn trening. Ingeniører trenger ikke et majestetisk rammeverk der; de trenger en modell som laster, kjører og holder seg innenfor harde begrensninger rundt minne, pakkestørrelse, energibruk og oppstartstid. TensorFlow Lite gir mening når selve utplasseringsmålet er den primære kraften som former arkitekturen. Moteksemplet er også vanlig: et team begynner med en edge-runtime fordi det høres effektivt ut, og deretter strekker det sakte inn i en bredere serverplattform eller en arbeidsflyt med mer dynamiske behov enn det ble bygget for å støtte. Effektivitet på kanten oversetter seg ikke automatisk til komfort alle andre steder.

Så er det llama.cpp, som fortjener spesiell oppmerksomhet fordi det endret det emosjonelle kartet over lokal slutning. Før llama.cpp og lignende prosjekter ble mainstream, antok mange ingeniører lokal storspråklig modellservering enten ville forbli et forskningsleketøy eller en bedriftsapparat. llama.cpp demonstrerte noe mer interessant: med aggressiv kvantisering, nøye kjernearbeid og disiplinert konstruksjon, kan en moderne LLM bli en lokal innfødt komponent i vanlige systemer. Den innsikten er viktig utover ett prosjekt. Det minnet hele feltet om at innfødt utførelse, modellkomprimering og praktisk distribusjon kan gå mye raskere enn sentraliserte fortellinger ofte antyder. Men llama.cpp har også en naturlig grense. Det er utmerket når jobben kjører støttede transformatormodeller lokalt og effektivt. Det er ikke en generell erstatning for hele dyplæringsøkosystemet, og team får problemer når de ber det om å bli ett.

Hvordan velge uten å bli forført av hype

Den mest pålitelige måten å velge mellom disse bibliotekene på er å begynne med produktet og først senere navngi verktøyet. Start med å spørre hva applikasjonen din egentlig eier og hva den bare bruker. Hvis systemet stort sett bruker en stabil modell og trenger bærbare, godt avgrensede slutninger, er ONNX Runtime ofte det roligste svaret. Hvis systemet i seg selv må snakke på språket til tensorer, moduler og rammesemantikk, fortjener LibTorch diskusjonen. Hvis CPU effektivitet, grafoptimalisering eller Intel-tung utrulling er den vanskelige delen, beveger oneDNN og OpenVINO seg nærmere midten. Hvis målet er lite, offline, batterifølsomt eller innebygd, blir TensorFlow Lite mer naturlig. Hvis produktet eksplisitt handler om å kjøre en lokal kvantisert språkmodell i et innfødt miljø, hører llama.cpp tidlig hjemme på bordet.

Et annet spørsmål er like viktig: hvor skal den tekniske smerten faktisk betales? Team velger ofte biblioteker i henhold til benchmark-overskrifter og oppdager deretter at deres virkelige smerte er et annet sted. En kjøretid med spektakulære gjennomstrømningstall kan fortsatt passe feil hvis eksporten er ustabil, forbehandlingen er rotete eller distribusjonspakningen blir sprø. En noe langsommere kjøretid kan fortsatt være det bedre forretningsvalget hvis det skaper en renere grense mellom modellprodusenter og systemvedlikeholdere. Ingeniører som har sendt mer enn ett AI-produkt lærer denne leksjonen dypt: det beste biblioteket gjør hele systemet lettere å tenke over klokken to om morgenen; referansegevinster alene avgjør ikke avgjørelsen.

Det er her moteksempler blir sunne. Vurder et team som bygger en innebygd dokumentanalysetjeneste. Det fasjonable valget kan være å strekke seg etter det tyngste rammeverket som er tilgjengelig, fordi det føles fremtidssikkert. Men hvis modellen er statisk, er forbehandlingsrørledningen enkel, og det virkelige behovet er stabil slutning i en eksisterende C++-tjeneste, vil ONNX Runtime sannsynligvis skape mindre langsiktig drag. Tenk nå på det motsatte. Et team utfører innfødte eksperimenter med tilpassede tensorflyter, hyppige arkitekturendringer og tett kobling til PyTorch-basert treningslogikk. Å tvinge alt gjennom ONNX fordi det høres "produksjonsklart" ut kan skape en skjør eksportsentrisk arbeidsflyt som ingen virkelig liker. I hvert tilfelle er feilen den samme: teamet valgte en identitet før det valgte en arbeidsmengde.

Hvordan god integrasjon faktisk ser ut

En moden integrasjonsarbeidsflyt begynner med datakontrakten, ikke biblioteket. Før du diskuterer kjøretider, avgjør hva applikasjonen gir modellen og hva modellen returnerer til applikasjonen. Navngi tensorformene, d-typene, normaliseringsregler, tokeniseringsbaner, polstringsadferd, batchforutsetninger og feiltilstander. Dette høres nesten byråkratisk ut, men det er den stille kilden til mange vellykkede distribusjoner. Systemer svikter når grensene rundt kjøretider er tåkete.

Når datakontrakten er stabil, blir eksport- eller modellemballasje mye enklere å validere. Et team kan sammenligne resultater mellom forskningsveien og produksjonsveien under representative input, måle toleranser og oppdage hvor troskap driver. Det er her ingeniører oppdager om deres elegante arkitektur overlever virkeligheten. Noen ganger er den eksporterte grafen fin, og det eneste problemet er feilaktig forbehandling. Noen ganger er kjøretiden feilfri, og det virkelige problemet er trådoverabonnement andre steder i tjenesten. Noen ganger kan ikke en visstnok liten modell overleve minnepresset av ekte samtidighet. Hver og en av disse oppdagelsene er nyttige. Det betyr at systemet har begynt å bli synlig.

Etter det kommer benchmarking og profilering, og her gjelder den samme gamle regelen: mål systemet du har tenkt å sende, ikke leken du pleide å føle deg smart. Benchmark modellen under realistiske forespørselsformer, batchstørrelser, inndatavariabilitet og maskinvareforhold. Profilforbehandling og etterbehandling også, fordi mange team ubevisst måler bare modellkjernen og glemmer at kundene betaler for hele veien. I produksjon AI, er en ti millisekunders graf omgitt av seksti millisekunder med unngåelig lim fortsatt en sytti millisekunders funksjon.

Til slutt, gjør distribusjonen reproduserbar. Innfødt AI stabler belønningsdisiplin. Pin-versjoner, dokumentkompilator og kjøretidsantakelser, avgjør hvilke utførelsesleverandører eller CPU-funksjoner som kreves, og hold et smalt sett med støttede konfigurasjoner. Hvis en lagkamerat ikke kan gjenskape den samme slutningsbanen på en annen maskin uten arkeologi, er ikke stabelen klar, uansett hvor imponerende demoen måtte ha vært. God C++ AI-teknikk gjør systemet rolig nok til at hastigheten forblir forståelig.

Feil som gjentar seg

Den vanligste feilen er å forveksle forskningssannhet med produksjonssannhet. En modell som ser utmerket ut i en bærbar PC kan bli vanskelig når den først er eksportert, kvantisert, innebygd, observert og kjørt under reell samtidighet. Det betyr ikke at modellen var dårlig. Det betyr at systemet var større enn eksperimentet. Den andre tilbakevendende feilen er å late som om forbehandling og etterbehandling er sekundære. I ekte produkter er de ofte halve arbeidet. Retningslinjer for endring av bildestørrelse, tokenizer-adferd, funksjonsnormalisering, kalibreringsterskler og utdatadekoding, all formkorrekthet og latens like sikkert som kjernekjøringen.

En tredje feil er overbinding til et rammeverk fordi det føles moderne eller omfattende. Ingeniører velger noen ganger det størst mulige verktøyet i påvente av behov som aldri kommer. Produktet betaler deretter for funksjoner det ikke bruker. Den motsatte feilen eksisterer også: å velge den letteste kjøretiden i renhets navn og deretter oppdage at dynamisk oppførsel, tilpassede operasjoner eller semantikk på rammenivå ikke var valgfrie likevel. Visdom ligger i å betale kun for kraften du faktisk kan forklare.

Det er også en mer subtil holdningssvikt. Noen team behandler bibliotekvalg som om det avgjør hele ingeniørhistorien. Det gjør det ikke. Gode ​​resultater kommer fra gjentatt, ydmykt arbeid: validering av utdata, måling av varme baner, fjerning av kopier som kan unngås, redusere oppstartsfriksjon, forenkle pakking og holde kjøretidsgrensen leselig. Åpen kildekode-biblioteker gjør dette arbeidet mulig; de utfører det ikke på våre vegne.

En liten distribusjonshistorie verdt å huske

Se for deg et team som begynner med en Python visjonsprototype. Demoen er sterk nok til å vinne intern støtte, og snart går samtalen over til integrasjon med en eksisterende C++-tjeneste som allerede håndterer bildeinntak, regelevaluering og rapportering. Laget har flere fristelser. Den ene er å beholde modellen bak en egen Python tjeneste for alltid fordi det er enkelt på kort sikt. En annen er å flytte alt inn i en tungvekts native ramme umiddelbart fordi det høres alvorlig ut. En tredje er å bruke uker på å krangle om arkitektur før man stabiliserer selv inngangskontrakten.

Den mer modne banen er roligere. Først definerer teamet preprosessering og utgangssemantikk nøye. Deretter tester den eksporttrohet på representative bilder. Den velger ONNX Runtime fordi problemet er statisk inferens og ikke rammestyrt eksperimentering. Senere, for en kantvariant med tøffere maskinvarebegrensninger, evaluerer den om TensorFlow Lite eller en mer aggressivt optimalisert kjøretidsbane er fornuftig for den produktgrenen. Måneder senere, hvis selskapet legger til en lokal assistentfunksjon, kan llama.cpp også gå inn i arkitekturen når hvert verktøy har fortjent sin plass i et annet hjørne av systemet.

Det er den dypere lærdommen bak alle disse bibliotekene. Seriøs AI ingeniørkunst belønner sjelden renhet. Det belønner passform. Det beste biblioteket med åpen kildekode er ikke det med høyest tilhengerskare. Det er den som lar modellen din bli en del av et reelt system uten å tvinge resten av systemet til å bli urimelig.

Hands-On Lab: Bygg en liten ONNX Runtime CLI

Teorien blir mer overbevisende når den kompileres.

La oss bygge det minste nyttige native inferensprogrammet i C++. Målet er ikke å trene en modell. Målet er å føle, med egne hender, hvordan en innfødt kjøretidsgrense ser ut.

For denne øvelsen trenger du:

  • en C++17 kompilator
  • CMake
  • en forhåndsbygd ONNX Runtime-pakke fra de offisielle utgivelsene
  • enhver liten .onnx-modell hvis inngang er en flat flyte-tensor

Prosjektoppsett

tiny-ort/
  CMakeLists.txt
  main.cpp
  third_party/
    onnxruntime/
  model.onnx

CMakeLists.txt

cmake_minimum_required(VERSION 3.16)
project(tiny_ort LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(ORT_ROOT "${CMAKE_SOURCE_DIR}/third_party/onnxruntime")

add_executable(tiny_ort main.cpp)
target_include_directories(tiny_ort PRIVATE "${ORT_ROOT}/include")

if (WIN32)
    target_link_directories(tiny_ort PRIVATE "${ORT_ROOT}/lib")
    target_link_libraries(tiny_ort PRIVATE onnxruntime)
else()
    target_link_directories(tiny_ort PRIVATE "${ORT_ROOT}/lib")
    target_link_libraries(tiny_ort PRIVATE onnxruntime)
endif()

main.cpp

#include <onnxruntime_cxx_api.h>

#include <array>
#include <iostream>
#include <numeric>
#include <vector>

int main() {
    Ort::Env env{ORT_LOGGING_LEVEL_WARNING, "tiny-ort"};
    Ort::SessionOptions opts;
    opts.SetIntraOpNumThreads(1);
    opts.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED);

    const ORTCHAR_T* model_path = ORT_TSTR("model.onnx");
    Ort::Session session{env, model_path, opts};

    std::vector<int64_t> shape{1, 4};
    std::vector<float> input{0.25f, 0.50f, 0.75f, 1.0f};

    auto mem_info = Ort::MemoryInfo::CreateCpu(
        OrtArenaAllocator,
        OrtMemTypeDefault
    );

    Ort::Value tensor = Ort::Value::CreateTensor<float>(
        mem_info,
        input.data(),
        input.size(),
        shape.data(),
        shape.size()
    );

    const char* input_names[] = {"input"};
    const char* output_names[] = {"output"};

    auto outputs = session.Run(
        Ort::RunOptions{nullptr},
        input_names,
        &tensor,
        1,
        output_names,
        1
    );

    float* out = outputs[0].GetTensorMutableData<float>();
    auto out_shape = outputs[0].GetTensorTypeAndShapeInfo().GetShape();
    auto out_count = std::accumulate(
        out_shape.begin(),
        out_shape.end(),
        int64_t{1},
        std::multiplies<int64_t>{}
    );

    std::cout << "Output values:\n";
    for (int64_t i = 0; i < out_count; ++i) {
        std::cout << "  [" << i << "] = " << out[i] << "\n";
    }

    return 0;
}

Bygge

På Linux eller macOS:

cmake -S . -B build
cmake --build build -j
./build/tiny_ort

På Windows med MSVC:

cmake -S . -B build
cmake --build build --config Release
.\build\Release\tiny_ort.exe

Hva dette lærer deg

Dette lille prosjektet tvinger deg allerede til å konfrontere flere produksjonsrealiteter:

  • hvor kjøretiden bor
  • hvordan native avhengigheter er pakket
  • hva tensornavn og former faktisk er
  • hvordan eksplisitt minnehåndtering føles i en innfødt slutningsgrense

Det er akkurat det som er poenget. Et bibliotek slutter å være et markedsføringsbegrep og blir et ingeniørvalg.

Testoppgaver for entusiaster

Hvis du vil gjøre artikkelen om til en helgelab, her er nyttige neste trinn:

  1. Erstatt den hardkodede inngangsvektoren med verdier lastet fra en liten tekst- eller binærfil.
  2. Skriv ut input og output tensorformer dynamisk i stedet for å anta dem.
  3. Legg til enkel latensmåling rundt session.Run og sammenlign 1, 2 og 4 intra-op tråder.
  4. Bytt ut ONNX Runtime med LibTorch i en lignende leketøysapp og skriv ned hva som ble lettere og hva som ble tyngre.
  5. Eksporter en liten modell fra Python, last den inn i dette C++-programmet, og kontroller at forhåndsbehandlingsforskjeller ikke i det stille endrer resultatet.

Hvis du gjør disse fem oppgavene ærlig, vil du forstå mer om AI utplassering enn mange mennesker som kan resitere rammenavn i en time.

Sammendrag

Åpen kildekode nevrale nettverksbiblioteker for C++ marsjerer ikke i én parade. De vokste ut av forskjellige ingeniørbehov, og de forblir mest nyttige når vi respekterer denne opprinnelsen. ONNX Runtime er kraftig fordi den begrenser problemet og gir produksjonsteam en stabil slutningsgrense. LibTorch er verdifull når den opprinnelige applikasjonen virkelig trenger tensor- og moduleierskap på tvers av modellbanen. oneDNN og OpenVINO betyr noe når lavnivåeffektivitet og distribusjon på spesifikke maskinvarefamilier slutter å være sekundære bekymringer. TensorFlow Lite skinner når selve enheten er den harde begrensningen. llama.cpp betyr noe fordi det beviste, veldig offentlig, at nøye native engineering kan gjøre moderne språkmodeller til praktiske lokale komponenter i stedet for fjerne tjenester.

Det beste valget er derfor sjelden det mest fasjonable. Det er den som gjør hele systemet roligere. En god kjøretid er en kjøretid som teamet ditt kan forstå, måle, profilere, pakke, teste og operere uten mytologi. Når ingeniører velger fra det stedet, slutter åpen kildekode AI å se ut som en forvirrende dyrehage av rammeverk og begynner å se ut som det den egentlig er: en verktøykasse rik nok til å støtte seriøse innfødte produkter.

Referanser

  1. ONNX Runtime C/C++ API: ONNX Runtime
  2. ONNX offisielt prosjekt: https://onnx.ai/
  3. PyTorch C++ frontenddokumentasjon: PyTorch
  4. oneDNN offisiell dokumentasjon: oneDNN
  5. OpenVINO dokumentasjon: OpenVINO
  6. LiteRT / TensorFlow Lite C++ API dokumenter: TensorFlow Lite
  7. llama.cpp repository: llama.cpp
  8. ONNX Runtime GitHub-depot: ONNX Runtime
  9. PyTorch depot: PyTorch

    Slik ser dette ut når systemet allerede er under trykk

C++ ai kjøretidsvalg har en tendens til å bli presserende akkurat i det øyeblikket et team håpet på et roligere kvartal. En funksjon er allerede foran kundene, eller en plattform har allerede intern avhengighet, og systemet har valgt den aktuelle uken for å avsløre at dens elegante teori og kjøretidsatferd har levd høflig separate liv. Dette er grunnen til at så mye seriøst ingeniørarbeid starter med forsoning. Teamet må forene hva det tror systemet gjør med det systemet faktisk gjør under belastning, under endring og under den slags tidsfrister som gjør alle litt mer kreative og litt mindre kloke.

I native AI-distribusjon er tilfellene som betyr mest, vanligvis portable server-slutninger, edge-distribusjon på begrenset maskinvare og innebygging av modeller i eksisterende native produkter. Disse situasjonene har tekniske, budsjettmessige, tillitsmessige, veikart og noen ganger omdømmekonsekvenser. Et teknisk problem blir politisk større i det øyeblikket flere lag er avhengige av det, og ingen kan helt forklare hvorfor det fortsatt oppfører seg som en vaskebjørn innenfor murene: bråkete om natten, vanskelig å finne og dyrt å ignorere.

Derfor anbefaler vi å lese problemet gjennom linsen av driftstrykk og leveringsrealitet. Et design kan være teoretisk vakkert og operasjonelt ødeleggende. Et annet design kan være nesten kjedelig og likevel bære produktet videre i årevis fordi det er målbart, reparerbart og ærlig om dets avveininger. Seriøse ingeniører lærer å foretrekke den andre kategorien. Det gir færre episke taler, men også færre nødretrospektiver der alle snakker passivt og ingen husker hvem som godkjente snarveien.

Praksis som konsekvent eldes godt

Den første varige praksisen er å holde én representativ bane under konstant måling. Lag samler ofte inn for mye vag telemetri og for lite signal av beslutningskvalitet. Velg veien som virkelig betyr noe, mål den gjentatte ganger, og nekt å la diskusjonen gå over i dekorativ historiefortelling. I arbeid rundt C++ AI kjøretidsvalg, er de nyttige målene vanligvis kjøretidstilpasning, integrasjonsfriksjon, pakkekostnader og steady-state latens. Når de først er synlige, blir resten av avgjørelsene mer menneskelige og mindre mystiske.

Den andre varige praksisen er å skille bevis fra løfte. Ingeniører blir ofte presset til å si at en retning er rett før systemet har fortjent den konklusjonen. Motstå det presset. Bygg først et smalt bevis, spesielt når emnet er nær kunder eller penger. En liten verifisert forbedring har mer kommersiell verdi enn en stor ubekreftet ambisjon. Dette høres åpenbart ut inntil en gjennomgang i kvart slutt gjør en hypotese til en deadline og hele organisasjonen begynner å behandle optimisme som en planleggingsartefakt.

Den tredje varige praksisen er å skrive anbefalinger på eierskapsspråket. Et avsnitt som sier «forbedre ytelsen» eller «styrke grenser» er følelsesmessig behagelig og driftsmessig ubrukelig. Et avsnitt som sier hvem som endrer hva, i hvilken rekkefølge, med hvilken tilbakerullingstilstand, er den som faktisk overlever mandag morgen. Det er her mye teknisk skriving feiler. Det vil høres avansert ut mer enn det ønsker å være planlagt.

Moteksempler som sparer tid

Et av de vanligste moteksemplene ser slik ut: teamet har en skarp lokal suksess, antar at systemet nå er forstått, og skalerer deretter ideen til et mye mer krevende miljø uten å oppgradere måledisiplinen. Det er den ingeniørmessige ekvivalenten til å lære å svømme i et hotellbasseng og deretter holde en selvsikker TED-foredrag om været til sjøs. Vann er vann helt til det ikke er det.

Et annet moteksempel er verktøyinflasjon. En ny profiler, en ny kjøretid, et nytt dashbord, en ny agent, et nytt lag med automatisering, en ny innpakning som lover å harmonisere den gamle innpakningen. Ingen av disse tingene er iboende dårlige. Problemet er hva som skjer når de blir bedt om å kompensere for en grense ingen har navngitt klart. Systemet blir da mer instrumentert, mer imponerende og bare av og til mer forståelig. Kjøpere føler dette veldig raskt. Selv uten den fraseringen kan de lukte når en stabel har blitt en dyr erstatning for en avgjørelse.

Det tredje moteksemplet er å behandle menneskelig vurdering som en automatiseringssvikt. I virkelige systemer er menneskelig vurdering ofte kontrollen som holder automatisering kommersielt akseptabel. Voksne team vet hvor de skal automatisere aggressivt og hvor de skal holde godkjenning eller tolkning synlig. Umodne team vil at maskinen skal gjøre alt fordi "alt" høres effektivt ut i et lysbilde. Så kommer den første alvorlige hendelsen, og plutselig gjenoppdages manuell gjennomgang med oppriktigheten til en konverteringsopplevelse.

Et leveringsmønster vi anbefaler

Hvis arbeidet blir utført godt, bør den første leveransen redusere stress ved å gi teamet en teknisk lesning som er sterk nok til å slutte å krangle i sirkler. Etter det bør den neste avgrensede implementeringen forbedre én avgjørende vei, og retesten bør gjøre retningen lesbar for både ingeniører og ledere. Denne sekvensen betyr mer enn det eksakte verktøyvalget fordi det er det som gjør teknisk ferdighet til bevegelse fremover.

Rent praktisk anbefaler vi en smal første syklus: samle artefakter, lag én hard diagnose, send én avgrenset endring, test den virkelige banen på nytt, og skriv neste avgjørelse på klart språk. Klart språk er viktig. En kjøper angrer sjelden på klarhet. En kjøper angrer ofte på å bli imponert før kvitteringene kommer.

Det er også her tonen betyr noe. Sterkt teknisk arbeid skal høres ut som det har møtt produksjon før. Rolig, presis og litt underholdt av hype i stedet for næret av den. Den tonen bærer driftssignal. Det viser at teamet forstår den gamle sannheten om systemteknikk: maskiner er raske, veikart er skjøre, og før eller siden kommer regningen for hver antagelse som fikk forbli poetisk.

Sjekklisten vi ville brukt før vi kaller denne klar

I innfødt AI-distribusjon er beredskap ikke en stemning. Det er en sjekkliste med konsekvenser. Før vi kaller arbeid rundt C++ AI kjøretidsvalg klar for en bredere utrulling, vil vi at et par ting skal være kjedelige på best mulig måte. Vi ønsker én vei som oppfører seg forutsigbart under representativ belastning. Vi ønsker ett sett med målinger som ikke motsier seg selv. Vi vil at laget skal vite hvor grensen går og hva det vil si å bryte den. Og vi vil at resultatet av arbeidet skal være tydelig nok til at noen utenfor implementeringsrommet fortsatt kan ta en fornuftig avgjørelse fra det.

Denne sjekklisten berører vanligvis kjøretidstilpasning, integrasjonsfriksjon, pakkekostnader og steady-state latens. Hvis tallene beveger seg i riktig retning, men teamet fortsatt ikke kan forklare systemet uten å improvisere, er ikke arbeidet klart. Hvis arkitekturen høres imponerende ut, men ikke kan overleve et beskjedent moteksempel fra feltet, er ikke verket klart. Hvis implementeringen eksisterer, men tilbakeføringshistorien høres ut som en bønn med tidsstempler, er ikke arbeidet klart. Ingen av disse er filosofiske innvendinger. De er ganske enkelt formene der dyre overraskelser har en tendens til å presentere seg selv.

Det er også her teamene oppdager om de løste det virkelige problemet eller bare øvde på kompetanse i dens generelle nærhet. Svært mange tekniske anstrengelser føles vellykket helt frem til noen ber om repeterbarhet, produksjonsbevis eller en beslutning som vil påvirke budsjettet. I det øyeblikket blir det svake verket uskarpt og det sterke verket blir merkelig enkelt. Vanlig er bra. Plain betyr vanligvis at systemet har sluttet å stole på karisma.

Hvordan vi anbefaler å snakke om resultatet

Den endelige forklaringen bør være kort nok til å overleve et ledermøte og konkret nok til å overleve en ingeniørgjennomgang. Det er vanskeligere enn det høres ut. Altfor teknisk språk skjuler sekvens. Altfor forenklet språk skjuler risiko. Den rette mellomveien er å beskrive veien, bevisene, den begrensede endringen og det neste anbefalte trinnet på en måte som høres rolig ut snarere enn triumferende.

Vi anbefaler en struktur som dette. Først si hvilken vei som ble evaluert og hvorfor den betydde noe. For det andre, si hva som var galt eller usikkert på den veien. For det tredje, si hva som ble endret, målt eller validert. For det fjerde, si hva som forblir uløst og hva den neste investeringen vil kjøpe. Den strukturen fungerer fordi den respekterer både ingeniør- og kjøpsatferd. Ingeniører vil ha detaljer. Kjøpere ønsker sekvensering. Alle vil ha færre overraskelser, selv de som later som de liker dem.

Den skjulte fordelen med å snakke på denne måten er kulturell. Team som forklarer teknisk arbeid tydelig, utfører det vanligvis også tydeligere. De slutter å behandle tvetydighet som raffinement. De blir vanskeligere å imponere med sjargong og lettere å stole på med vanskelige systemer. Det er en av de mer undervurderte formene for ingeniørmodenhet.

Hva vi fortsatt vil nekte å forfalske

Selv etter at systemet har forbedret seg, holder modne team usikkerheten ærlig i den opprinnelige AI-distribusjonen. Svak måling trenger klarere bevis, harde grenser trenger klart språk, og roligere demoer trenger reell operativ beredskap. Noe usikkerhet må reduseres; noen må nevnes ærlig. Å forveksle disse to jobbene er hvordan respektable prosjekter blir dyre lignelser.

Den samme regelen gjelder for beslutninger rundt C++ AI kjøretidsvalg. Hvis et team fortsatt mangler en reproduserbar målestokk, en pålitelig tilbakeføringsvei eller en tydelig eier for det kritiske grensesnittet, kan det mest nyttige resultatet være et skarpere nei eller et smalere neste trinn i stedet for et større løfte. Denne disiplinen holder teknisk arbeid på linje med virkeligheten det er ment å forbedre.

Det er en merkelig lettelse ved å jobbe på denne måten. Når systemet ikke lenger er avhengig av optimistisk historiefortelling, blir ingeniørsamtalen enklere, selv når arbeidet fortsatt er hardt. Og i produksjon som ofte teller som en mindre form for nåde.

Feltnotater fra en ekte teknisk gjennomgang

I C++ systemlevering blir arbeidet seriøst når demoen møter reell levering, reelle brukere og reelle driftskostnader. Det er øyeblikket hvor en ryddig idé begynner å oppføre seg som et system, og systemer har en kjent tørr sans for humor. De bryr seg ikke om hvor elegant kickoff-dekket så ut. De bryr seg om grenser, feilmoduser, utrullingsveier og om noen kan forklare neste trinn uten å finne opp en ny mytologi rundt stabelen.

For Using Open-Source Libraries for Neural Networks in C++ er det praktiske spørsmålet om det skaper en sterkere leveringsvei for en kjøper som allerede har press på et veikart, en plattform eller en sikkerhetsgjennomgang. Den kjøperen trenger ikke et foredrag polert til tåke. De trenger en teknisk lesning de kan bruke.

Hva vi ville inspisert først

Vi vil begynne med én representativ vei: innfødt slutning, profilering, HFT-baner, DEX-systemer og C++/Rust moderniseringsvalg. Den veien bør være smal nok til å måle og bred nok til å avsløre sannheten. Den første passeringen bør fange opp allokeringsatferd, p99-latens, profilbevis, ABI friksjon og frigjøre tillit. Hvis disse signalene er utilgjengelige, er prosjektet fortsatt for det meste opinion iført laboratoriefrakk, og opinion har en lang historie med å fakturere seg selv som strategi.

Den første nyttige artefakten er et innfødt system som leses med benchmarks, profileringsbevis og en omfattende implementeringsplan. Det skal vise systemet slik det oppfører seg, ikke slik alle håpet det skulle oppføre seg i planleggingsmøtet. Et spor, en reprise, en liten målestokk, en policymatrise, en parser-armatur eller en repeterbar test forteller ofte historien raskere enn en annen abstrakt arkitekturdiskusjon. Gode ​​gjenstander er fantastisk frekke. De avbryter ønsketenkning.

Et moteksempel som sparer tid

Den dyre feilen er å svare med en løsning som er større enn det første nyttige beviset. Et team ser risiko eller forsinkelse og strekker seg umiddelbart etter en ny plattform, en omskriving, en feiende refactor eller et innkjøpsvennlig dashbord med et navn som høres ut som det gjør yoga. Noen ganger er den skalaen berettiget. Svært ofte er det en måte å utsette målingen på.

Det bedre trekket er mindre og skarpere. Gi navn til grensen. Ta bevis. Endre en viktig ting. Test den samme banen på nytt. Bestem deretter om neste investering fortjener å bli større. Denne rytmen er mindre dramatisk enn et transformasjonsprogram, men den har en tendens til å overleve kontakt med budsjetter, utgivelseskalendere og produksjonshendelser.

Leveringsmønsteret anbefaler vi

Det mest pålitelige mønsteret har fire trinn. Først samler du representative gjenstander. For det andre, gjør disse artefaktene til en vanskelig teknisk diagnose. For det tredje, send en avgrenset endring eller prototype. For det fjerde, test på nytt med samme måleramme og dokumenter neste avgjørelse i klartekst. I denne klassen er CMake-armaturer, profileringsseler, små native repros og kompilator-/kjøretidsnotater vanligvis mer verdifulle enn et annet møte om generell retning.

Klart språk er viktig. En kjøper bør være i stand til å lese produksjonen og forstå hva som endret seg, hva som forblir risikabelt, hva som kan vente, og hva neste trinn vil kjøpe. Hvis anbefalingen ikke kan planlegges, testes eller tildeles en eier, er den fortsatt for dekorativ. Dekorativ teknisk skrift er hyggelig, men produksjonssystemer er ikke kjent for å belønne hygge.

Hvordan bedømme om resultatet hjalp

For Open-Source Neural Network Libraries in C++: ONNX Runtime, LibTorch, oneDNN, OpenVINO, TFLite, llama.cpp bør resultatet forbedre minst én av tre ting: leveringshastighet, systemsikkerhet eller kommersiell beredskap. Hvis det ikke forbedrer noen av disse, kan teamet ha lært noe, men kjøperen har ennå ikke mottatt et nyttig resultat. Det skillet er viktig. Læring er edelt. Et betalt engasjement bør også flytte systemet.

Det sterkeste resultatet kan være et smalere veikart, et avslag på å automatisere en farlig vei, en bedre grense rundt en modell, en renere innfødt integrasjon, et målt bevis på at en omskriving ikke er nødvendig ennå, eller en kort utbedringsliste som ledelsen faktisk kan finansiere. Seriøs ingeniørkunst er en sekvens av bedre beslutninger, ikke en kostymekonkurranse for verktøy.

Hvordan SToFU ville tilnærmet seg det

SToFU vil behandle dette som et leveringsproblem først og et teknologiproblem dernest. Vi ville bringe den relevante tekniske dybden, men vi ville holde engasjementet forankret til bevis: banen, grensen, risikoen, målingen og den neste endringen som er verdt å gjøre. Poenget er ikke å få hardt arbeid til å høres enkelt ut. Poenget er å gjøre det neste seriøse grepet klart nok til å gjennomføre.

Det er den delen kjøpere vanligvis setter høyest. De kan ansette meninger hvor som helst. Det de trenger er et team som kan inspisere systemet, navngi den virkelige begrensningen, bygge eller validere den riktige delen, og etterlate artefakter som reduserer forvirring etter at samtalen er avsluttet. I et støyende marked er ikke klarhet en myk ferdighet. Det er infrastruktur.

Philip P.

Philip P. – CTO

Tilbake til blogger

Kontakt

Start samtalen

Noen klare linjer er nok. Beskriv systemet, trykket og beslutningen som er blokkert. Eller skriv direkte til midgard@stofu.io.

01 Hva systemet gjør
02 Hva gjør vondt nå
03 Hvilken avgjørelse er blokkert
04 Valgfritt: logger, spesifikasjoner, spor, diff
0 / 10000
Ingen fil er valgt