Γρήγορες ενσωματώσεις σε GPUs
Αυτό το άρθρο παρουσιάζει μια ματιά εκ των έσω στην υποδομή εξυπηρέτησης της Perplexity για αυτήν την ειδική κατηγορία μοντέλων.
Η γρήγορη και ακριβής αναζήτηση είναι ζωτικής σημασίας για ολόκληρη την Perplexity, από την Αναζήτηση και το Computer μέχρι την πλατφόρμα API μας. Στα παρασκήνια, τη βαριά δουλειά κάνουν τα μοντέλα ενσωμάτωσης και κατάταξης, τα οποία βοηθούν τα συστήματά μας να εντοπίσουν τα πιο σχετικά αποτελέσματα για ένα δεδομένο ερώτημα. Επιτυγχάνουμε ποιότητα και καθυστέρηση αιχμής εκπαιδεύοντας και εξυπηρετώντας τα δικά μας μοντέλα, όπως το pplx-embed.
Αυτό το άρθρο παρουσιάζει μια ματιά στα παρασκήνια της υποδομής εξυπηρέτησης της Perplexity για αυτήν την ειδική κατηγορία μοντέλων. Συζητούμε τις τεχνικές μας για την αποτελεσματική αντιμετώπιση των αναγκών εξαγωγής συμπερασμάτων της αναζήτησης με έμφυτη τεχνητή νοημοσύνη, επιτρέποντας τη γρήγορη δημιουργία πρωτοτύπων και αξιολόγηση μοντέλων, τροφοδοτώντας παράλληλα τον δείκτη αναζήτησης κλίμακας exabyte. Αυτές οι τεχνικές συλλογικά διευρύνουν το σύνορο Pareto ποιότητας και αποδοτικότητας αναζήτησης, επιτρέποντάς μας να εξυπηρετούμε πράκτορες και χρήστες με τα καλύτερα δυνατά αποτελέσματα με το χαμηλότερο δυνατό κόστος και καθυστέρηση.
Ενσωματώσεις για αναζήτηση
Σε μια τυπική ρύθμιση αναζήτησης, τα ευρετηριασμένα έγγραφα χαρτογραφούνται σε έναν διανυσματικό χώρο υψηλών διαστάσεων χρησιμοποιώντας ένα μοντέλο ενσωμάτωσης και αποθηκεύονται σε μια διανυσματική βάση δεδομένων. Με την ενσωμάτωση ενός ερωτήματος με το ίδιο μοντέλο, μπορούν να εντοπιστούν παρόμοια έγγραφα βρίσκοντας τα διανύσματα που βρίσκονται πιο κοντά σε αυτό του ερωτήματος. Αυτό δημιουργεί δύο διαφορετικά μοτίβα κυκλοφορίας για την εξυπηρέτηση ενός μηχανισμού εξαγωγής συμπερασμάτων:
- Μαζική Ενσωμάτωση: κατά την κατασκευή, επέκταση ή επανευρετηρίαση της βάσης δεδομένων, τα μαζικά έγγραφα πρέπει να ενσωματωθούν στον διανυσματικό χώρο, μεγιστοποιώντας την απόδοση για την ελαχιστοποίηση του κόστους.
Μετά την αναζήτηση διανυσμάτων, μεγάλες παρτίδες εγγράφων πρέπει να βαθμολογηθούν, επιτυγχάνοντας μια ισορροπία μεταξύ απόδοσης και καθυστέρησης.
- Online Ενσωμάτωση: κατά την υποβολή ερωτήματος στη βάση δεδομένων, ένα σύντομο ερώτημα πρέπει να ενσωματωθεί για αναζητήσεις, ελαχιστοποιώντας την καθυστέρηση.
Χτίσαμε την υποδομή inference μας ώστε να αξιοποιεί όσο το δυνατόν περισσότερα κοινά στοιχεία μεταξύ διαφορετικών χρήσεων. Επειδή συνήθως χρησιμοποιούμε μικρά μοντέλα Transformer για να παράγουμε embeddings, μοιραζόμαστε το μεγαλύτερο μέρος της υλοποίησης με τον κώδικα inference των LLM μας: τα batch embeddings μοιάζουν με το compute-bound prefill, ενώ τα online embeddings, που συχνά εκτελούνται σε λίγα tokens, είναι υπολογιστικά παρόμοια με το memory-bound decode. Έτσι επαναχρησιμοποιούμε τους βελτιστοποιημένους kernels prefill και decode μας για την εξυπηρέτηση μοντέλων embeddings. Ως αποτέλεσμα, μπορούμε να πετύχουμε τεράστια throughput batch inference με ελάχιστη πρόσθετη μηχανική εργασία, διατηρώντας παράλληλα χαμηλή καθυστέρηση για online workloads embeddings.
Tulips, Roses, and some Ivy
Εκθέτουμε την εξαγωγή συμπερασμάτων μέσω τυποποιημένων API, τόσο εσωτερικά όσο και εξωτερικά μέσω της πλατφόρμας API μας. Στα παρασκήνια, πολλαπλές υπηρεσίες εμπλέκονται στην επεξεργασία ενός αιτήματος ενσωμάτωσης:
- Το Ivy είναι μια πύλη HTTP Rust που καλούν οι υπηρεσίες της Perplexity.
Χειρίζεται την εργασία στην πλευρά της CPU για αιτήματα όπως η ανάλυση JSON, το tokenization, η δημιουργία προτύπων εισόδου και ο διαχωρισμός παρτίδων, μεταφράζοντας τα αιτήματα σε ένα προσαρμοσμένο πρωτόκολλο gRPC για διακομιστές κατάντη (downstream). Αυτός ο διαχωρισμός μας επιτρέπει να διαμορφώνουμε ορισμένες παραμέτρους γύρω από το tokenization και τη μορφοποίηση εισόδου χωρίς να χρειάζεται να αγγίξουμε τις βαρύτερες περιπτώσεις εξαγωγής συμπερασμάτων.
- Το Tulip είναι η διεπαφή διακομιστή εξαγωγής συμπερασμάτων.
Είναι ένας διακομιστής gRPC υλοποιημένος με Rust, tokio και tonic. Το Tulip λαμβάνει αιτήματα εξαγωγής συμπερασμάτων gRPC, διαχειριζόμενο τον προγραμματισμό και την ομαδοποίηση. Στη συνέχεια, στέλνει τις ομάδες στη μηχανή ROSE, επιστρέφοντας ολοκληρωμένες απαντήσεις στους πελάτες.
Ορίζεται κυρίως σε Python, παρέχοντας kernels, επίπεδα και ορισμούς για μια μεγάλη ποικιλία μοντέλων. Το ROSE υλοποιεί τα περάσματα προς τα εμπρός μέσω μοντέλων, παρέχοντας επίσης διαχείριση γραφημάτων CUDA εξειδικευμένη για ενσωματώσεις. Συνδέεται με το Tulip μέσω μιας συνάρτησης step(), η οποία λαμβάνει μια παρτίδα και επιστρέφει μια αναφορά στον υπολογισμό που εκτελεί στον επιταχυντή.
Δίνοντας προσοχή πέρα από το Kernel
Τόσο τα μοντέλα που βασίζονται σε Transformer όσο και οι υποκείμενες αρχιτεκτονικές Hopper/Blackwell είναι ώριμες τεχνολογίες, επομένως η ενσωμάτωση της εξαγωγής συμπερασμάτων στην πλευρά της GPU έχει συγκεντρωθεί σε μια σε μεγάλο βαθμό βέλτιστη υλοποίηση σε διάφορους μηχανισμούς εξαγωγής συμπερασμάτων. Παρόλα αυτά, ανακαλύψαμε επιπλέον ευκαιρίες βελτίωσης στους χρόνους εκτέλεσης και στα εργαλεία που εκθέτουν τα μοντέλα από άκρο σε άκρο σε έναν πελάτη. Ειδικότερα, διαπιστώσαμε ότι μπορούμε να βελτιώσουμε τις καθυστερήσεις διαχειριζόμενοι προσεκτικά τα γραφήματα CUDA και κατασκευάζοντας μια αφαίρεση LazyTensor για την ασύγχρονη παρακολούθηση ενός αποτελέσματος στην πλευρά της GPU στον εγγενή μηχανισμό Rust. Υλοποιήσαμε αυτά τα χαρακτηριστικά στο Tulip, ώστε να μπορεί να διασυνδεθεί αποτελεσματικά με τις υλοποιήσεις μοντέλων του ROSE.
Tulip
Σχεδιάσαμε το Tulip ώστε να είναι μια όσο το δυνατόν πιο ελαφριά διεπαφή πάνω από την εξυπηρέτηση του μοντέλου μας. Χειρίζεται τα εισερχόμενα αιτήματα σε ασύγχρονες εργασίες Tokio, διατηρώντας μια ομάδα αιτημάτων που παρακολουθεί και από την οποία προγραμματίζει παρτίδες προς αποστολή στον επιταχυντή. Ο μηχανισμός προγραμματισμού στο Tulip είναι πολύ απλός: τα αιτήματα συσσωρεύονται ενώ το Tulip αποστέλλει εργασία ή περιμένει αποτελέσματα. Από τα συσσωρευμένα αιτήματα, οι ακολουθίες επιλέγονται με βάση τη σειρά προτεραιότητας (first-come, first-served) για να εκτελεστούν μέσω του μοντέλου.
Ο απλός μηχανισμός προγραμματισμού υποκινείται από μια παρατήρηση σχετικά με την απόδοση του μοντέλου. Για μικρά μοντέλα ενσωμάτωσης, στα μήκη ακολουθίας που εξυπηρετούμε, παρατηρήσαμε ότι το γραμμικό κόστος των πυκνών επιπέδων κυριαρχεί έναντι του τετραγωνικού κόστος της προσοχής. Επομένως, η καθυστέρηση είναι κυρίως ανάλογη με τον αριθμό των tokens, όχι τον αριθμό των ακολουθιών. Κατά συνέπεια, μόλις μια παρτίδα είναι αρκετά μεγάλη ώστε να κορεστεί η GPU, η οποία είναι γύρω στα 512 tokens σε ένα μοντέλο κάτω του ενός δισεκατομμυρίου παραμέτρων, η συσκευασία περισσότερων ακολουθιών σε αυτήν δεν βελτιώνει την αποδοτικότητα.
Για να διασυνδεθεί αποτελεσματικά με το μοντέλο, το Tulip βασίζεται σε γραφήματα CUDA και παρακολούθηση αποτελεσμάτων lazy για την επικάλυψη εργασιών GPU και CPU και την πλήρη αξιοποίηση των διαθέσιμων πόρων.
Διαχείριση γραφημάτων CUDA
Η εκτέλεση του περάσματος προς τα εμπρός ενός μοντέλου περιλαμβάνει εργασίες τόσο στην πλευρά της CPU όσο και στην πλευρά της GPU. Η CPU είναι υπεύθυνη για τον προγραμματισμό παρτίδων και την εκκίνηση kernels με τις κατάλληλες παραμέτρους, ενώ η GPU εκτελεί τα σχετικά kernels πολλαπλασιασμού πινάκων, προσοχής (attention), κανονικοποίησης (norm) ή ενεργοποίησης. Για φόρτους εργασίας υψηλής απόδοσης, όπως η εκπαίδευση και η εκ νέου ευρετηρίαση, τα γενικά έξοδα της πλευράς της CPU είναι αμελητέα επειδή τα μεγέθη παρτίδων και η καθυστέρηση της πλευράς της GPU είναι και τα δύο μεγάλα. Ωστόσο, σε μικρότερα μεγέθη παρτίδων, η εργασία της πλευράς της CPU μπορεί να υπερισχύσει της εργασίας της πλευράς της GPU.
Για να μετριαστούν τα γενικά έξοδα, αντί να εκκινούνται ανεξάρτητα kernels, μπορεί να κατασκευαστεί ένα γράφημα CUDA για την καταγραφή των μεταδεδομένων που απαιτούνται για την εκκίνηση όλων των kernels ενός περάσματος προς τα εμπρός με μία μόνο κλήση στον οδηγό CUDA. Αυτό εξαλείφει την ανάγκη επανεκτέλεσης δαπανηρού κώδικα Python και PyTorch για τις διαμορφώσεις για τις οποίες μπορούν να καταγραφούν τα γραφήματα CUDA.
Σε κάθε μοντέλο, παρακολουθούμε ένα σημείο καμπής, προσδιορίζοντας τον ελάχιστο αριθμό tokens στον οποίο η εκτέλεση σε GPU είναι πιο δαπανηρή από την εκκίνηση πυρήνα στην πλευρά της CPU. Επειδή τα μοντέλα ενσωμάτωσης είναι μικρά, παρατηρούμε ότι αυτό το σημείο καμπής έρχεται σε παρτίδες χιλιάδων tokens και δεκάδων ακολουθιών. Ορισμένες υλοποιήσεις προσοχής βασίζονται σε δυναμικές εισόδους στην πλευρά του κεντρικού υπολογιστή για τη διαμόρφωση εκκινήσεων πυρήνα, αποτρέποντας τα πλήρη γραφήματα CUDA prefill/dense μοντέλου. Ανεβάσαμε upstream αλλαγές στα σχετικά kernels για να τα ενεργοποιήσουμε στον μηχανισμό εξαγωγής συμπερασμάτων μας.
Για την αντιμετώπιση των γενικών εξόδων, κατασκευάζουμε γραφήματα CUDA ολόκληρου του μοντέλου για όλα τα μοντέλα ενσωμάτωσης και επικαλύπτουμε την εργασία CPU με εργασία GPU. Δεδομένου ότι τα γραφήματα CUDA ελαχιστοποιούν τα γενικά έξοδα της πλευράς της CPU, μόλις εκκινηθεί ένα γράφημα, έχουμε ελεύθερο χρόνο για να ξεκινήσουμε και να βάλουμε στην ουρά την εκτέλεση της επόμενης παρτίδας όποτε είναι διαθέσιμη. Τα αποτελέσματα της εκκρεμούς παρτίδας παρακολουθούνται με ένα LazyTensor, το οποίο επιτρέπει σε μια ασύγχρονη εργασία στη Rust να μπλοκάρει έως ότου ολοκληρωθεί η εκτέλεση της προηγούμενης παρτίδας. Τα γραφήματα CUDA βοηθούν στην εξυπηρέτηση χαμηλής καθυστέρησης διασφαλίζοντας ότι δεν καθυστερούμε από το κόστος εκκίνησης kernels και διευκολύνουν τη βελτιωμένη προγραμματισμού στην περίπτωση υψηλής απόδοσης καθώς ελευθερώνουν την CPU να εργαστεί στην επόμενη παρτίδα νωρίτερα.
Τα γραφήματα CUDA πρέπει να καταγράφονται για κάθε ξεχωριστή διαμόρφωση, γεγονός που για τις ενσωματώσεις σημαίνει ένα γράφημα ανά συνδυασμό μέτρησης ακολουθίας και μέτρησης token. Δεδομένου ότι αυτό το πλέγμα είναι εκτεταμένο, κάνουμε padding στις μετρήσεις token σε κάδος (buckets) που είναι πολλαπλάσια του 64 ή του 256. Αυτό εξακολουθεί να έχει ως αποτέλεσμα χιλιάδες γραφήματα που ενδέχεται να χρειαστούν πολλαπλά λεπτά για να καταγραφούν για ένα τυπικό μοντέλο. Το κόστος της καταγραφής προέρχεται από δύο πηγές: ένα άμεσο πέρασμα προς τα εμπρός που πρέπει να εκτελεστεί για τη μεταγλώττιση kernels και τη ρύθμιση buffers για διάφορα kernels που τα χρειάζονται, ακολουθούμενο από την εκτέλεση καταγραφής που επανεκτελεί κώδικα Python.
Μετριάζουμε το κόστος εκκίνησης καταγράφοντας γραφήματα CUDA lazy καθώς ο μηχανισμός εξυπηρετεί. Παρακολουθούμε κάθε διαμόρφωση και διασφαλίζουμε ότι περνάει από μια άμεση εκτέλεση προθέρμανσης πριν ενεργοποιήσουμε την καταγραφή γραφήματος και την επανάληψη στη δεύτερη επιτυχία. Όλες οι επόμενες εκτελέσεις της ίδιας διαμόρφωσης γραφήματος περνούν στη συνέχεια από επανάληψη γραφήματος CUDA. Η lazy καταγραφή γραφημάτων έχει αντίκτυπο στις καθυστερήσεις p99 κατά την εκκίνηση· ωστόσο, είναι πολύτιμη για τη διασπορά πολλαπλών λεπτών άμεσης εργασίας σε πολλαπλές ώρες. Οι γρηγορότεροι χρόνοι εκκίνησης μας επιτρέπουν να κλιμακώνουμε και να διαχειριζόμαστε καλύτερα τις αναπτύξεις ενσωμάτωσης.
Lazy Tensors
Μέσω της CUDA, η εργασία της GPU είναι ασύγχρονη. Δεδομένου ότι η εκκίνηση ενός kernel ασύγχρονα το τοποθετεί στην ουρά σε μια ροή, ο κώδικας του κεντρικού υπολογιστή πρέπει να συγχρονίζεται ρητά για να διαβάσει τα προκύπτοντα διανύσματα. Για να διευκολυνθεί ένας υψηλότερος βαθμός παραλληλισμού και να είναι δυνατή η εκκίνηση μελλοντικών παρτίδων ενώ περιμένουμε την ολοκλήρωση της προηγούμενης στη συσκευή, βασιζόμαστε σε μια αφαίρεση LazyTensor για την παρακολούθηση τιμών.
Το LazyTensor παρακολουθεί μια μνήμη buffer κεντρικού υπολογιστή σε μνήμη κλειδωμένης σε σελίδα (page-locked) και μια λειτουργία cudaMemcpyAsync μέσω ενός συμβάντος που αντιγράφει δεδομένα από τη συσκευή. Ξεκινά μετά την εκκίνηση του περάσματος προς τα εμπρός στην ίδια ροή (stream). Δεδομένου ότι η λειτουργία αντιγραφής πρέπει να περιμένει την εκτέλεση όλων των προηγούμενων kernels στη ροή, το σχετικό συμβάν παρακολουθεί τόσο την ολοκλήρωση του περάσματος προς τα εμπρός όσο και τη διαθεσιμότητα του αποτελέσματος στην CPU.
Αξιοποιούμε LazyTensors στη μηχανή κωδικοποιητή ROSE για την επικάλυψη εργασιών GPU και CPU. Αντί κάθε κλήση step() να εκτελεί το γράφημα CUDA και να περιμένει να ολοκληρωθεί, η συνάρτηση step() επιστρέφει ένα LazyTensor για την ασύγχρονη παρακολούθηση του αποτελέσματός της. Σε συνδυασμό με τα γραφήματα CUDA, αυτό μας βοηθά να πετύχουμε χαμηλές καθυστερήσεις και καλύτερη απόδοση.
ROSE
Προσαρμόσαμε τον μηχανισμό ROSE, τον οποίο είχαμε αρχικά κατασκευάσει για εξυπηρέτηση LLM, ώστε να χειρίζεται επίσης την εκτέλεση μοντέλων ενσωμάτωσης. Για να ελαχιστοποιηθεί η προσπάθεια που απαιτείται για την υποστήριξη μοντέλων ενσωμάτωσης, το ROSE επαναχρησιμοποιεί επιθετικά κώδικα μεταξύ LLM και ενσωματώσεων. Για παράδειγμα, η εξυπηρέτηση pplx-embed και η αποκωδικοποίηση LLM Qwen3.5 περνούν όλα από τα ίδια kernels. Αυτός ο διαμοιρασμός μας επιτρέπει να εξυπηρετούμε εύκολα ένα μοντέλο ενσωμάτωσης που αρχικά είχε ρυθμιστεί λεπτομερώς (fine-tuned) από ένα LLM για τη δημιουργία πρωτοτύπων, την αξιολόγηση και την εξαγωγή συμπερασμάτων παραγωγής.
Για πυκνά επίπεδα, η ενσωμάτωση και η εξαγωγή συμπερασμάτων LLM είναι πανομοιότυπες, καθώς τα διανύσματα tokens επεξεργάζονται ανεξάρτητα. Στα επίπεδα προσοχής, οι διαφορές αντιμετωπίζονται με την προσθήκη υποστήριξης για ακανόνιστες εισόδους (ragged inputs), μαζί με τις ρυθμίσεις paged prefill και decode που απαιτούνται από τα LLM. Κατά την εξυπηρέτηση ενός μοντέλου ενσωμάτωσης, δεν στιγμιότυπουποιούμε μια κρυφή μνήμη KV (KV cache) και αποστέλλουμε σε παραλλαγές kernels προσοχής που υποστηρίζουν την ακανόνιστη μορφή για την αποφυγή padding. Οι υποστηρικτικές ουσίες μετατροπής και βαθμονόμησης μοιράζονται επίσης με τα LLM.
Ivy
Το Ivy, το επίπεδο HTTP proxy της υποδομής inference μας, παίζει επίσης σημαντικό ρόλο στην απόδοση. Επειδή τα payloads των αιτημάτων διαφέρουν στην παραγωγή, η δρομολόγηση μεμονωμένων αιτημάτων σε μεμονωμένα replicas μπορεί να οδηγήσει σε ανισορροπία φόρτου. Το Ivy χωρίζει τα μεγάλα batch αιτήματα σε chunks και τα εξισορροπεί φορτίου μεταξύ των replicas, βελτιώνοντας την αξιοποίηση και εξομαλύνοντας την καθυστέρηση. Η πρόσφατη δουλειά μας στην εσωτερική unigram tokenization, που έχει αναπτυχθεί πλήρως στο Ivy, βελτιώνει δραστικά τις καθυστερήσεις σε σχέση με τα έτοιμα tokenizers.
...αλλά τα Kernels εξακολουθούν να μετρούν
Το ROSE υποστηρίζει μια ποικιλία από attention backends. Διαφορετικοί kernels μπορεί να είναι κατάλληλοι για συγκεκριμένα μεγέθη προβλημάτων. Με την πάροδο του χρόνου, ενσωματώσαμε kernels FlashInfer 2, FlashInfer 3 και FlashAttention 4 για την υλοποίηση ragged attention.
Γενικά, παρατηρούμε ότι το FlashAttention 4 είναι ταχύτερο. Ωστόσο, το FlashInfer 3 το ξεπερνά σε μοντέλα που βασίζονται στο Qwen σε πολύ μεγάλα μήκη ακολουθίας. Δεδομένου ότι η απόδοση και η ρύθμιση μπορεί να διαφέρουν ανάλογα με τον αριθμό και τη διάσταση των κεφαλών προσοχής, διατηρούμε την υποστήριξη για πολλαπλές διαμορφώσεις και λαμβάνουμε απόφαση κατά περίπτωση κατά την εξυπηρέτηση.
Benchmarks
Κάνουμε συγκριτική αξιολόγηση (benchmark) έναντι του vLLM v0.22.0, εκτελώντας εξαγωγή συμπερασμάτων σε ακρίβεια BF16 σε πραγματικά βάρη μοντέλων και εισόδους που προέρχονται από σύνολα δεδομένων αξιολόγησης. Όλες οι εκτελέσεις χρονομέτρησης προηγήθηκαν από εκτελέσεις προθέρμανσης που επαλήθευσαν ότι η απόκλιση στην ομοιότητα συνημιτόνου είναι εντός 0,1%.
Ενσωματώσεις χαμηλής καθυστέρησης (p50 / p90 / p99 / μέγ. ms)
Αναφέρουμε χρόνους εκτέλεσης για μέγεθος παρτίδας προ-tokenized αιτημάτων 1, πλήρως διαδοχικά αιτήματα, μήκη ακολουθίας 128, 512 και 4096 tokens.
Βαθμολόγηση χαμηλής καθυστέρησης (p50 / p90 / p99 / μέγ. ms)
Μεγέθη παρτίδων προ-tokenized αιτημάτων 5, 25 και 50, μήκος ακολουθίας 512 tokens.
Ενσωματώσεις υψηλής απόδοσης (emb/s)
Μέγεθος παρτίδας αιτημάτων 100, τέσσερις ταυτόχρονες διεργασίες υποβολής αιτημάτων, μήκη ακολουθίας 512, 1024 και 4096 tokens.
Ενσωματώσεις υψηλής ταυτόχρονης εκτέλεσης (p50 / p90 / p99 / μέγ. ms)
Μήκος ακολουθίας 512, μέγεθος παρτίδας 1, αλλά στέλνουμε 1, 2, 4, 8 και 16 ταυτόχρονα αιτήματα. Αυτό το benchmark περιλαμβάνει επίσης το κόστος tokenization μέσω του Ivy, μαζί με το υπερβολικό κόστος δικτύου μεταξύ Ivy και Tulip.
Συμπέρασμα και μελλοντική εργασία
Η υποδομή εξυπηρέτησης που αποτελείται από τα Ivy, Tulip και ROSE μας επιτρέπει να εξυπηρετούμε ενσωματώσεις για την Perplexity με χαμηλότερη καθυστέρηση και καλύτερη απόδοση, με αποτέλεσμα ακριβέστερη αναζήτηση σε μειωμένο κόστος σε σύγκριση με τις έτοιμες λύσεις.
Εστιάζοντας σε συγκεκριμένα μοντέλα και αναλαμβάνοντας την ευθύνη ολόκληρης της στοίβας, αποκτούμε την απαραίτητη ελευθερία για να επιτύχουμε μια αποτελεσματική ισορροπία μεταξύ απόδοσης και ευελιξίας, συνδυάζοντας εξαιρετικά επαναχρησιμοποιήσιμα και αποδοτικά πρωτογενή στοιχεία Rust παράλληλα με πιο γενικό κώδικα μοντελοποίησης Python. Πολλοί μηχανισμοί εξαγωγής συμπερασμάτων ανοιχτού κώδικα, όπως οι vLLM, SGLang και TokenSpeed, ενσωματώνουν γλώσσες όπως η Rust και η C++ στη στοίβα τους. Έχουμε επενδύσει στη Rust τα τελευταία δύο χρόνια και έχουμε αποκομίσει εξαιρετικά οφέλη τόσο στην απόδοση όσο και στη δυνατότητα συντήρησης. Μοιραζόμενοι το μεγαλύτερο μέρος της υλοποίησης ενσωμάτωσης με τη στοίβα εξυπηρέτησης LLM, απολαμβάνουμε επίσης κέρδη στην απόδοση, χωρίς να απαιτείται η διάθεση σημαντικού μηχανικού κόπου για τη συντήρηση μοντέλων ενσωμάτωσης.
Καθώς τα μοντέλα εξελίσσονται, θα συνεχίσουμε να βελτιώνουμε κάθε επίπεδο της στοίβας μας ώστε να μειώσουμε τόσο τις καθυστερήσεις περιορισμένες από CPU όσο και τις καθυστερήσεις περιορισμένες από GPU. Τα custom πρωτόκολλά μας βασισμένα σε gRPC μέσα στα Ivy και Tulip μάς επιτρέπουν να προσαρμόζουμε την επικοινωνία ώστε να μειώνουμε τις καθυστερήσεις δικτύου, ενώ το ROSE παρέχει ένα θεμέλιο για τη βελτίωση της υπολογιστικής throughput. Επιπλέον, καθώς η υποστήριξη για free-threaded Python μεγαλώνει σε όλο το οικοσύστημα, θα μπορέσουμε να βελτιώσουμε περαιτέρω τη διαλειτουργικότητα Python-Rust για να μειώσουμε τα overheads.
Παραπομπές
- Αρχιτεκτονική και αξιολόγηση ενός API αναζήτησης με έμφαση στην τεχνητή νοημοσύνη
- pplx-embed: Μοντέλα ενσωμάτωσης αιχμής για ανάκτηση κλίμακας ιστού
- Βελτίωση της απόδοσης CPU του Unigram Tokenizer
- vLLM
- FlashInfer
- FlashAttention
Παραπομπή
@online{perplexity2026FastEmbeddingsOnGpus,
author = {{Perplexity} and Nandor Licker and Sebastian Sepulveda and Phi Hoang and Jerry Ma},
title = {{Fast embeddings on GPUs}},
date = {2026-09-04},
url = {https://www.perplexity.ai/hub/blog/fast-embeddings-on-gpus}
}