In 2016 bouwde ons team een zoektool voor premiumdomeinen, ontworpen om direct tijdens het typen vergelijkbare domeinen op de secundaire markt te vinden. We gebruikten fastText-embeddings met Spotify’s Annoy-indexering voor semantisch zoeken in minder dan 10 ms.
In tegenstelling tot traditionele domeinzoekers die alleen beschikbaarheid controleren, probeerde onze tool de bedoeling van de gebruiker te begrijpen. Wanneer iemand ‘instantdomainsearch.com’ zoekt, vindt onze index domeinen met een vergelijkbare betekenis:
- domaininstant.com
- fastdomainsearch.com
- searchdomain.com
De valkuilen van fastText: domeinspecifieke context
fastText leerde zijn begrip van betekenis uit miljarden woorden in Common Crawl en Wikipedia. Maar domeinen vertegenwoordigen bedrijven en merken, die woorden vaak anders gebruiken dan algemene webteksten.
Neem ‘mint’ als voorbeeld. fastText herkent beide betekenissen, maar geeft veel hogere overeenkomstscores aan planten- en kruidentermen. In de wereld van domeinen en bedrijven wordt ‘mint’ vaker met geld geassocieerd, bijvoorbeeld Mint.com. Dat patroon herhaalde zich bij veel termen, zoals Cloud en Spark.
| Verwant woord | fastText-overeenkomst met ‘mint’ | Context |
|---|---|---|
peppermint | 0.64 (hoog) | Plant/kruid |
| herb | 0.49 | Plant/kruid |
money | 0.37 | Geld/financiën |
finance | 0.29 | Geld/financiën |
budget | 0.27 (laag) | Geld/financiën |
We beseften dat dit geen beperking van fastText was. Domeinnamen hebben hun eigen semantische betekenis ontwikkeld.
Dat bracht ons bij een uitdaging: hoe konden we ons model context geven die specifiek is voor domeinnamen?
Waarom niet gewoon AI gebruiken?
Moderne LLM’s begrijpen context uitstekend. Toen we GPT-4 testten voor vergelijkbare domeinsuggesties, begreep het duidelijk welke betekenissen gebruikers verwachtten.
Met een korte prompt voor domeinspecifieke context begreep het dat ‘cloud’ ook cloudcomputing betekent, ‘mint’ financiën en ‘spark’ data-analyse. Het stelde domeinen voor die passen bij wat kopers echt willen, niet alleen tekstvarianten.
Maar er was een doorslaggevend obstakel: latentie. Ons fastText-systeem geeft resultaten binnen 10 ms. GPT-4 deed er gemiddeld 1,7 seconden over, 85 keer langzamer. Bij een tool waarvan gebruikers resultaten tijdens het typen verwachten, zou meer dan een seconde wachten per toetsaanslag de ervaring vernietigen.
Embedding-modellen: van woorden naar concepten
Dat bracht ons op het idee om LLM’s niet realtime te gebruiken, maar offline om ons eigen snelle embeddingmodel te trainen. Zo kreeg het geen algemene webcontext, maar context voor onze specifieke toepassing: domeinen.
Dit zijn de praktische verschillen:
De fastText-aanpak (algemeen betekenisbegrip):
- Gebruikt 2 miljoen woordvectoren, getraind op Common Crawl (2017)
- Begrijpt verbanden tussen woorden op basis van hun gebruik in webteksten
- ‘searchengine’ = semantische betekenis uit miljoenen zinnen
- Uitstekend in algemeen taalbegrip
Onze verbeterde aanpak (betekenis voor domeinnamen):
- Behandelt elk woord en elke uitdrukking als een bedrijfsconcept
- ‘searchengine’ = ‘Een platform om op internet te zoeken en dingen te ontdekken’
- Voegt domeinspecifieke context toe die fastText nooit heeft gezien
- Bouwt met moderne technieken voort op de basis van fastText
Hiervoor gebruikten we sentence-transformers, een Python-bibliotheek die modernere embeddingmodellen voor semantisch zoeken ondersteunt. Die konden we fijn afstemmen op onze specifieke toepassing. Het AI-landschap is sinds 2017 sterk veranderd, waardoor gespecialiseerde modellen veel gemakkelijker te bouwen zijn. We gebruikten GPT-4 om in batches miljoenen domeinspecifieke trainingsvoorbeelden te genereren. Vervolgens stemden we deze nieuwere modellen af om domeinen te begrijpen zoals domeinhandelaren dat doen.
De implementatie vergde vijf stappen: trainingsgegevens genereren, overeenkomsten berekenen, de training structureren, het model fijn afstemmen en optimaliseren voor productiesnelheid.
Stap 1: domeinbeschrijvingen genereren met GPT-4
We ontdekten dat GPT-4 uitstekend is in het uitbreiden van losse woorden tot rijke contextbeschrijvingen. Met alleen een domeinnaam kon het mogelijke toepassingen, verwante branches en betekenisverbanden afleiden.
| Domein | Door GPT-4 gegenereerde beschrijving | Geëxtraheerde zoekwoorden |
|---|---|---|
| torontopancakes.com | Een aantrekkelijke naam die de charme van Toronto combineert met de liefde voor pannenkoeken, perfect voor ontbijtliefhebbers en stadsverkenners. | food, breakfast, pancakes, maple syrup, Canada, Toronto, brunch, treats, sweet, delicious, local, community |
| matchupitchutours.com | Een reisgerichte naam geïnspireerd op Machu Picchu, voor rondleidingen en onvergetelijke avonturen in de Andes. | travel, tours, adventure, Peru, Machu Picchu, history, culture, nature, explore, hiking, mountains, guide |
| frankenbergerschokolade.com | Een rijke, verwennerij uitstralende naam die de charme van Duits erfgoed met de zoetheid van chocolade combineert, perfect voor gastronomische lekkernijen en zoetwaren. | chocolate, gourmet, sweets, German, heritage, desserts, artisan, cocoa, indulgence, handmade, treats, premium |
Door beschrijvingen voor een deel van ons aanbod te genereren, kregen we gelabelde trainingsgegevens die de betekenis van domeinen vastlegden.
Stap 2: beschrijvingen omzetten in gelijkenisscores
Met beschrijvingen voor elk domein konden we betekenisovereenkomst meten met bestaande embeddingmodellen. Dat gaf ons referentiegegevens over welke domeinen als verwant moesten gelden:
| Domeinpaar | Overeenkomstscore | Soort verband |
|---|---|---|
| google.com ↔ searchengine.com | 0.68588746 | Dezelfde categorie |
| cloudeous.com ↔ cloudivio.com | 0.82812774 | Vergelijkbaar concept |
| omnigenics.com ↔ omniparent.com | 0.66224474 | Alleen gedeeld voorvoegsel |
| xaute.com ↔ paveup.com | 0.50881153 | Niet verwant |
Deze overeenkomstscores werden onze trainingsdoelen. Ze vertelden ons model welke domeinen in de embeddingruimte dicht bij elkaar of juist ver uit elkaar moesten liggen.
Stap 3: trainingstriplets maken voor fine-tuning
Training met triplet loss vereist gegevens in groepen van drie: een ankerdomein, een positieve match (vergelijkbaar) en een negatieve match (ongelijk). We genereerden duizenden van deze triplets uit onze overeenkomstberekeningen:
| Ankerdomein | Positieve match (vergelijkbaar) | Negatieve match (ongelijk) |
|---|---|---|
| google.com | searchengine.com (0.6858) | flowershop.com (0.2754) |
| uber.com | rideshare.com (0.7139) | cookbook.net (0.2201) |
| shopify.com | ecommerce.com (0.6064) | weatherapp.org (0.2656) |
Deze structuur dwingt het model relatieve overeenkomsten te leren in plaats van absolute classificaties.
Stap 4: ons domeinspecifieke embedding-model trainen
We kozen all-MiniLM-L6-v2 als basismodel en gebruikten all-mpnet-base-v2 voor de eerste embeddings. Het biedt een goede balans tussen prestaties en omvang. Met triplet loss trainden we het om het betekenisbegrip van GPT-4 na te bootsen:
| Trainingsmaatstaf | Waarde |
|---|---|
| Basismodel | all-MiniLM-L6-v2 |
| Trainingsvoorbeelden | 500,000 |
| Epochs | 25 |
| Uiteindelijke correlatie met GPT-4 | ~0.87 |
De correlatie van 0,87 betekende dat ons lichte model het grootste deel van het betekenisbegrip van GPT-4 vastlegde, terwijl het ordes van grootte sneller draaide.
Stap 5: optimaliseren van ~500 ms naar 10 ms
De eerste versie van deze nieuwe architectuur werd in Python geïmplementeerd om hypotheses te testen. We gebruikten gangbare bibliotheken zoals usearch voor HNSW en SQLite om resultaten aan domeinen te koppelen. Dat gaf veelbelovende resultaten, meestal rond 500 ms, en liet zien dat we op de goede weg waren. Een goed model trainen loste de helft van het probleem op. We hadden nog steeds een latentie onder 50 ms nodig!
Het grootste deel van onze infrastructuur is al in Rust geschreven. Daarom besloten we ook deze nieuwere modellen naar Rust te brengen. Om zware afhankelijkheden te vermijden, en omdat Torch niet het snelst is voor inferentie, kozen we ONNX Runtime.
- Modelformaat: ONNX (3 keer sneller dan PyTorch)
- Runtime: Rust + ort (minimale overhead, uitstekende CPU-prestaties)
- Index: HNSW voor een beperkte set van ongeveer 25 miljoen domeinen op de secundaire markt
- Hardware: alleen CPU’s, zonder coördinatieoverhead voor GPU’s
- Optimalisaties: gekwantiseerde, geoptimaliseerde uitvoer (optimum)
Het resultaat: een latentie van 10 ms op het 95e percentiel, binnen ons doel van 25 ms. Die snelheid is essentieel voor de directe zoekervaring die we via onze CDN-infrastructuur hebben geoptimaliseerd.
AI in ontwikkeling versus productie
‘AI-gestuurd’ betekent vaak dat een LLM in elk verzoekpad wordt geïntegreerd. Maar waar je AI inzet, is een ontwerpkeuze met duidelijke afwegingen.
- Tijdens ontwikkeling: minder context, hogere snelheid
- In productie: meer context, lagere snelheid
Onze directe zoekfunctie laat zien hoe ver de eerste aanpak kan komen: we distilleerden GPT-4-kennis met een biljoen parameters in een embeddingmodel met 22,7 miljoen parameters. Dat geeft semantische resultaten binnen 10 ms, afgezien van de afstand tussen de gebruiker en onze servers.
Onze bedrijfsnaamgenerator laat juist zien waar een live LLM sterker is: merkideeën vragen om frisse, brede redeneringen. Daarom ruilen we snelheid in voor diepgang en leveren we suggesties die echt de context van meer dan een biljoen parameters nodig hebben.
Daarmee zeggen we niet dat LLM’s tijdens ontwikkeling beter zijn dan LLM’s in productie. Het gaat om de juiste verhouding tussen contextdiepte en latentiekosten.
We zijn van plan ons nieuwe model in de komende maand uit te rollen.