Jag heter Pavel Parkhomenko och jag Àr ML-utvecklare. I den hÀr artikeln skulle jag vilja berÀtta om hur Yandex Zen-tjÀnsten fungerar och dela med mig av tekniska förbÀttringar som har gjort det möjligt att öka kvaliteten pÄ rekommendationerna. I inlÀgget kommer du att lÀra dig hur man hittar de mest relevanta dokumenten för anvÀndaren bland miljoner dokument pÄ bara nÄgra millisekunder; hur man gör kontinuerlig nedbrytning av en stor matris (som bestÄr av miljoner kolumner och tiotals miljoner rader), sÄ att nya dokument fÄr sin vektor pÄ bara nÄgra minuter; hur man ÄteranvÀnder nedbrytning av matrisen anvÀndare-artikel för att fÄ en bra vektorreprÀsentation för videor.

VÄr rekommendationsdatabas innehÄller miljoner dokument i olika format: textartiklar skapade pÄ vÄr plattform och hÀmtade frÄn externa webbplatser, videor, berÀttelser och korta inlÀgg. Utvecklingen av en sÄdan tjÀnst Àr kopplad till ett stort antal tekniska utmaningar. HÀr Àr nÄgra av dem:
- Dela upp berÀkningsuppgifterna: alla tunga operationer ska göras offline, medan vi endast ska utföra snabb tillÀmpning av modeller i realtid för att svara inom 100-200 ms.
- Snabbt ta hÀnsyn till anvÀndarens handlingar. För detta behöver alla hÀndelser omedelbart levereras till rekommendatorn och pÄverka modellernas resultat.
- Göra flödet sÄ att det snabbt anpassar sig till nya anvÀndares beteende. Nya anvÀndare som just kommit in i systemet mÄste kÀnna att deras feedback pÄverkar rekommendationerna.
- Snabbt förstÄ vem man ska rekommendera en ny artikel till.
- Omedelbart reagera pÄ det stÀndiga flödet av nytt innehÄll. Tiotusentals artiklar publiceras varje dag, och mÄnga av dem har en begrÀnsad livslÀngd (lÄt oss sÀga nyheter). Detta skiljer dem frÄn filmer, musik och annat lÄnglivat och kostsamt innehÄll.
- Ăverföra kunskaper frĂ„n ett domĂ€nomrĂ„de till ett annat. Om det finns utbildade modeller för textartiklar i rekommendationssystemet och vi lĂ€gger till videor kan vi Ă„teranvĂ€nda befintliga modeller sĂ„ att nytt innehĂ„ll rankas bĂ€ttre.
Jag kommer att berÀtta hur vi löste dessa uppgifter.
Urval av kandidater
Hur man pÄ nÄgra millisekunder kan minska mÀngden dokument som övervÀgs tusenfalt, utan att försÀmra rankingkvaliteten avsevÀrt?
Anta att vi har trÀnat mÄnga ML-modeller, genererat funktioner baserade pÄ dem och trÀnat en annan modell som rankar dokument för anvÀndaren. Det skulle vara bra, men man kan inte bara berÀkna alla funktioner för alla dokument i realtid, om det handlar om miljontals dokument och rekommendationer mÄste byggas pÄ 100-200 ms. Utmaningen Àr att vÀlja ett delmÀngd av miljontals dokument som ska rankas för anvÀndaren. Steget kallas vanligtvis kandidatselektion. Det finns flera krav pÄ detta steg. För det första mÄste valet gÄ mycket snabbt sÄ att det finns sÄ mycket tid som möjligt kvar för sjÀlva rankningen. För det andra, genom att kraftigt minska antalet dokument för rankning, mÄste vi bevara sÄ relevanta dokument för anvÀndaren som möjligt.
VÄr princip för kandidatselektion har utvecklats över tid, och just nu har vi kommit fram till ett flerlagersschema:

Först delas alla dokument upp i grupper, och frÄn varje grupp vÀljs de mest populÀra dokumenten. Grupper kan vara webbplatser, Àmnen, kluster. För varje anvÀndare anges de nÀrmaste grupperna baserat pÄ dess historik, och de bÀsta dokumenten tas frÄn dessa. Vi anvÀnder dessutom ett kNN-index för att snabbt kunna hitta de mest relevanta dokumenten för anvÀndaren i realtid. Det finns flera metoder för att bygga kNN-index, och vÄr metod som har funkat bÀst Àr (Hierarchical Navigable Small World graphs). Detta Àr en hierarkisk modell som gör det möjligt att pÄ nÄgra millisekunder hitta de N nÀrmaste vektorerna för anvÀndaren frÄn en bas av miljoner. Vi indexerar hela vÄr dokumentbas offline i förvÀg. Eftersom sökningen i indexet gÄr ganska snabbt kan man, vid tillgÄng till flera starka inbÀddningar, skapa flera index (ett för varje inbÀddning) och fÄ Ätkomst till var och en av dem i realtid.
Vi har tiotusentals dokument för varje anvĂ€ndare. Det Ă€r fortfarande mycket att rĂ€kna pĂ„ alla attribut, sĂ„ i det hĂ€r steget tillĂ€mpar vi en lĂ€tt rangordning â en förenklad modell av tung rangordning med fĂ€rre attribut. MĂ„let Ă€r att förutsĂ€ga vilka dokument som kommer att hamna pĂ„ toppen hos den tunga modellen. Dokument med högst prediktion kommer att anvĂ€ndas i den tunga modellen, det vill sĂ€ga i det sista rangordningssteget. Denna metod gör att vi pĂ„ nĂ„gra tiotal millisekunder kan minska mĂ€ngden dokument som övervĂ€gs för anvĂ€ndaren frĂ„n miljoner till tusentals.
ALS-steget i realtid
Hur beaktar man anvÀndarfeedback direkt efter klick?
En viktig faktor i rekommendationer Àr responstiden pÄ anvÀndarfeedback. Detta Àr sÀrskilt viktigt för nya anvÀndare: nÀr en person först börjar anvÀnda rekommendationssystemet fÄr han en opersonifierad flöde av dokument av olika Àmnen. SÄ snart han gör sitt första klick mÄste detta beaktas omedelbart och anpassas efter hans intressen. Om man berÀknar alla faktorer offline blir systemets snabba respons omöjlig pÄ grund av fördröjning. SÄ det Àr nödvÀndigt att bearbeta anvÀndarens ÄtgÀrder i realtid. För detta syfte anvÀnder vi ALS-steget i realtid för att bygga en vektorrepresentation av anvÀndaren.
Anta att vi har en vektorrepresentation för alla dokument. Till exempel kan vi offline bygga inbÀddningar baserade pÄ texten i artikeln med hjÀlp av ELMo, BERT eller andra maskininlÀrningsmodeller. Hur fÄr man en vektorrepresentation av anvÀndarna i samma rum baserat pÄ deras interaktioner i systemet?
Den allmĂ€nna principen för att bilda och dekomponera anvĂ€ndardokumentmatrisenLĂ„t oss sĂ€ga att vi har m anvĂ€ndare och n dokument. För vissa anvĂ€ndare Ă€r deras relation till vissa dokument kĂ€nd. Denna information kan dĂ„ representeras i en matris m x n: raderna motsvarar anvĂ€ndarna och kolumnerna â dokumenten. Eftersom de flesta dokument en person inte har sett, kommer en stor del av cellerna i matrisen att förbli tomma, medan andra kommer att fyllas i. För varje hĂ€ndelse (gilla, ogilla, klicka) finns det ett visst vĂ€rde i matrisen â men lĂ„t oss övervĂ€ga en förenklad modell dĂ€r ett gilla motsvarar 1, och ett ogilla â1.
Vi delar upp matrisen i tvĂ„: P (m x d) och Q (d x n), dĂ€r d Ă€r dimensionen av den vektoriska representationen (vanligtvis ett litet tal). DĂ„ motsvarar varje objekt en d-dimensionell vektor (anvĂ€ndaren â en rad i matrisen P, dokumentet â en kolumn i matrisen Q). Dessa vektorer kommer att vara inbĂ€ddningar av motsvarande objekt. För att förutsĂ€ga om en anvĂ€ndare kommer att gilla ett dokument kan vi helt enkelt multiplicera deras inbĂ€ddningar.

Ett av de möjliga sÀtten att dekonstruera matrisen Àr ALS (Alternating Least Squares). Vi kommer att optimera följande förlustfunktion:

HĂ€r Ă€r rui â interaktionen mellan anvĂ€ndaren u och dokumentet i, qi â vektorn för dokument i, pu â vektorn för anvĂ€ndare u.
DÄ hittas den optimala vektorn för anvÀndaren (med fasta dokumentvektorer) analytiskt genom att lösa den motsvarande linjÀra regressionen.
Detta kallas "steget ALS". SjÀlva algoritmen för ALS gÄr ut pÄ att vi vÀxelvis hÄller en av matriserna (anvÀndarna och artiklarna) fixa och uppdaterar den andra, med mÄlet att hitta den optimala lösningen.
Lyckligtvis Àr det en ganska snabb operation att hitta den vektoriska representationen av anvÀndaren, vilken kan göras i realtid med hjÀlp av vektorinstruktioner. Denna trick gör att vi genast kan ta hÀnsyn till anvÀndarens feedback i rankningen. Samma inbÀddning kan ocksÄ anvÀndas i kNN-indexet för att förbÀttra urvalet av kandidater.
Distribuerad kollaborativ filtrering
Hur man gör inkrementell distribuerad matrisfaktorisering och snabbt finner den vektoriska representationen av nya artiklar?
InnehÄll Àr inte den enda kÀllan till signaler för rekommendationer. En annan viktig kÀlla Àr den kollaborativa informationen. Bra indikationer för rangordning kan traditionellt fÄs genom att bryta ner anvÀndardokumentmatrisen. Men nÀr vi försökte göra en sÄdan nedbrytning stötte vi pÄ problem:
1. Vi har miljoner dokument och tiotals miljoner anvÀndare. Matrisen fÄr inte plats pÄ en enda dator, och nedbrytningen kommer att ta vÀldigt lÄng tid.
2. Den största delen av innehÄllet i systemet har kort livslÀngd: dokumenten förblir relevanta endast i nÄgra timmar. DÀrför Àr det nödvÀndigt att skapa deras vektorrepresentation sÄ snabbt som möjligt.
3. Om nedbrytningen görs direkt efter publiceringen av dokumentet kommer det inte att ha utvÀrderats av tillrÀckligt mÄnga anvÀndare. DÀrför kommer dess vektorrepresentation med stor sannolikhet att vara av ganska dÄlig kvalitet.
4. Om en anvÀndare ger en positiv eller negativ feedback kan vi inte direkt beakta detta i nedbrytningen.
För att lösa de nÀmnda problemen har vi implementerat en distribuerad nedbrytning av anvÀndardokumentmatrisen med frekventa inkrementella uppdateringar. Hur fungerar detta?
Anta att vi har en kluster av N datorer (N rÀkna hundratals) och vi vill göra en distribuerad nedbrytning av matrisen som inte fÄr plats pÄ en enda dator. FrÄgan Àr hur vi ska genomföra denna nedbrytning sÄ att, Ä ena sidan, varje dator har tillrÀckligt med data och, Ä andra sidan, att berÀkningarna Àr oberoende?

Vi kommer att anvĂ€nda den ovan beskrivna ALS-nedbrytningsalgoritmen. LĂ„t oss se hur ett steg av ALS utförs i distribuerad form â de övriga stegen kommer att vara liknande. Anta att vi har lĂ„st dokumentmatrisen och vi vill bygga anvĂ€ndarmatrisen. För detta kommer vi att dela upp den i N delar efter rader, varje del kommer att innehĂ„lla ungefĂ€r lika mĂ„nga rader. Vi skickar icke-tomma celler frĂ„n aktuella rader till varje dator, samt hela dokumentens embeddingsmatris. Eftersom den inte har sĂ„ stor storlek och anvĂ€ndardokumentmatrisen vanligtvis Ă€r mycket gles, fĂ„r dessa data plats pĂ„ en vanlig dator.
Denna teknik kan upprepas under flera epoker tills modellens konvergens, genom att vÀxla den fasta matrisen. Men Àven dÄ kan matrisfaktorisering ta flera timmar. Och det löser inte problemet att snabbt fÄ inbÀddningar för nya dokument och uppdatera inbÀddningar för dem som hade lite information nÀr modellen byggdes.
Vi har hjĂ€lpt till med att införa en snabb inkrementell uppdatering av modellen. Anta att vi har en aktuell trĂ€nad modell. Sedan dess har nya artiklar dykt upp, som vĂ„ra anvĂ€ndare har interagerat med, samt artiklar som hade lite interaktion under trĂ€ningen. För att snabbt fĂ„ inbĂ€ddningar för sĂ„dana artiklar anvĂ€nder vi inbĂ€ddningar för anvĂ€ndare som fick under den första stora trĂ€ningen av modellen, och vi gör ett steg av ALS för att berĂ€kna dokumentmatrisen med en fast anvĂ€ndarmatris. Detta möjliggör att fĂ„ inbĂ€ddningar ganska snabbt â inom nĂ„gra minuter efter publiceringen av dokumentet â och ofta uppdatera inbĂ€ddningar för nya dokument.
För att anvÀndarens handlingar ska beaktas omgÄende anvÀnder vi inte anvÀndarinbÀddningarna som erhölls offline i realtid. IstÀllet gör vi ett steg av ALS och fÄr den aktuella anvÀndarvektorn.
Ăverföring till ett annat domĂ€nomrĂ„de
Hur kan vi anvÀnda anvÀndarfeedback pÄ textartiklar för att skapa en vektorrepresentation av videor?
Inledningsvis rekommenderade vi endast textartiklar, sÄ mÄnga av vÄra algoritmer Àr anpassade för denna typ av innehÄll. Men nÀr vi lade till innehÄll av annan typ stÀlldes vi inför behovet av att anpassa modellerna. Hur löste vi denna uppgift med videoinnehÄll? Ett alternativ Àr att trÀna om alla modeller frÄn grunden. Men detta tar tid, dessutom Àr vissa algoritmer krÀvande nÀr det kommer till storleken pÄ trÀningsdata, som Ànnu inte finns i tillrÀcklig mÀngd för det nya typen av innehÄll under de första ögonblicken av dess liv pÄ tjÀnsten.
Vi valde en annan vÀg och ÄteranvÀnde textmodeller för videor. I skapandet av vektorreprÀsentationer av videor hjÀlpte samma trick med ALS oss. Vi tog anvÀndarnas vektorreprÀsentation baserad pÄ textartiklar och gjorde ett ALS-steg, med hjÀlp av information om videovisningar. SÄ vi fick enkelt vektorreprÀsentationen av videon. Vid körning berÀknar vi bara nÀrheten mellan anvÀndarens vektor, som erhÄllits baserat pÄ textartiklar, och videovektorn.
Slutsats
Utvecklingen av kÀrnan i det realtidsbaserade rekommendationssystemet Àr förenad med mÄnga utmaningar. Det krÀvs snabb databehandling och tillÀmpning av ML-metoder för att effektivt anvÀnda dessa data; bygga komplexa distribuerade system som kan bearbeta anvÀndarsignaler och nya innehÄllsenheter pÄ minimal tid; och mÄnga andra uppgifter.
I det nuvarande systemet, vars arkitektur jag beskrev, ökar kvaliteten pÄ rekommendationerna för anvÀndaren i takt med hans aktivitet och den tid han spenderar pÄ tjÀnsten. Men sjÀlvklart ligger den största svÄrigheten hÀr: systemet har svÄrt att snabbt förstÄ intressena hos en person som har interagerat minimalt med innehÄllet. FörbÀttringen av rekommendationer för nya anvÀndare Àr vÄr centrala uppgift. Vi kommer att fortsÀtta optimera algoritmerna sÄ att relevant innehÄll snabbare nÄr deras flöde, medan irrelevant innehÄll inte visas.
KĂ€lla: habr.com
