Големите јазични модели (LLMs) се насекаде, од секојдневните апликации до напредните алатки. Користењето на нив е лесно. Но што ако треба да го покренете сопствениот модел? Без разлика дали имате фино прилагоден модел или се занимавате со податоци кои се чувствителни на приватност, комплексноста се зголемува. Во овој пост, ќе го споделиме она што го научивме додека го градевме нашиот сопствен систем за заклучување на LLM. Ќе ги покриеме моделите за складирање и распоредување, дизајнирање на архитектурата на услугите и решавање на реални прашања како што се рутирање, стримирање и управување со микро-услуги. Процесот вклучува предизвици, но на крајот изградивме сигурен систем и собравме лекции вреди да се споделат. Воведување LLMs се напојуваат широк спектар на апликации - од chatbots и агенти за работен тек до паметен алатки за автоматизација. Додека генерирање, повикување на алатки и протоколи за повеќе агенти се важни, тие работат на ниво над основниот мотор: основен LLM. Многу проекти се потпираат на надворешни провајдери, како што , на или , што е доволно за повеќето случаи на употреба. Но, за одредени апликации, тоа брзо станува проблем. Што ако провајдерот падне? Што ако ви треба целосна контрола над латенцијата, цените или времето на работење? Најважното – што ако ви е грижа за приватноста и не можете да си дозволите да ги испратите податоците на корисниците на трета страна? Отворени Близнаци антрополошки Отворени Близнаци антрополошки Тоа е местото каде што само-хостинг станува неопходен. Служењето на преттрениран или фино прилагоден модел обезбедува контрола, безбедност и способност да се прилагоди моделот на специфични деловни потреби. Изградбата на таков систем не бара голем тим или обемни ресурси. Го изградивме со скромен буџет, мал тим и само неколку јазли. Ова ограничување влијаеше на нашата архитектонска одлука, барајќи од нас да се фокусираме на практичноста и ефикасноста. Во следните делови ќе ги покриеме предизвиците со кои се соочуваме, решенијата имплементирани и лекциите научени на патот. Општ преглед Овие се основните компоненти кои го сочинуваат 'рбетот на системот. Формати и кодирање Еден заеднички јазик низ услугите е од суштинско значење.Тоа значи конзистентни формати на барање / одговор, шеми на параметри за генерирање, структури на историјата на дијалогот и серијализација која работи насекаде - од фронт-енд до бацкенд до модел тркачи. Стреаминг и рутирање. Ракувањето со повеќе модели, типови на барања и приоритети на домаќинот бара свесни одлуки за рутирање. Ќе опишеме како влезните барања на корисниците се рутираат низ системот - од почетната точка на влез до соодветниот работен јазол - и како одговорите се пренесуваат назад. Модел складирање и имплементација. Каде живеат модели, и како тие се подготвени за употреба во производството? Ќе разговараме за клучните тестови што треба да се изведат, вклучувајќи го и обезбедувањето на сигурноста на моделот. Набљудуваност. Како знаете дека работите работат? Ние ќе ви покажеме кои метрики ги следиме, како ги следиме неуспесите и собите што ги користиме за да се обезбеди здравјето и сигурноста на системот. Схема и кодирање на податоци Изборот на вистинската шема за пренос на податоци е од суштинско значење. Споделен формат на услугите ја поедноставува интеграцијата, ги намалува грешките и ја подобрува прилагодливоста. Зошто дизајнот на шемата е важен Не постои универзален стандард за размена на податоци LLM. Многу провајдери ги следат шемите слични на Додека другите – како или Многу од овие провајдери нудат OpenAI компатибилни SDK-и кои ја задржуваат истата шема, иако често со ограничувања или намалени опции (на пример, , на Други проекти како што се Целта е да се обединат овие варијации со вградување во OpenAI компатибилен интерфејс. Отварање на Клод Близнаци OpenAI компатибилен SDK на Anthropic Gemini OpenAI слој на компатибилност Отвореникот Отварање на Клод Близнаци OpenAI компатибилен SDK на Anthropic Gemini OpenAI слој на компатибилност Отвореникот Придржувањето кон една однапред дефинирана шема на провајдерот има свои предности: Ќе добиете добро тестиран, стабилен API. Можете да се потпрете на постоечките SDK и алатки. Но, постојат и реални недостатоци: Тоа создава продавач-заклучување, што го отежнува поддржувањето на повеќе провајдери. Ограничува флексибилност за проширување на шемата со прилагодени карактеристики потребни за деловните потреби или барањата на тимот за податоци. Вие сте изложени на промени или намалувања надвор од вашата контрола. Овие шеми често носат наследни ограничувања кои ја ограничуваат фината контрола. За да го решиме ова прашање, одлучивме да го дефинираме нашиот - шема дизајнирана околу нашите потреби, која потоа можеме да ја нацртаме во различни надворешни формати кога е потребно. own internal data model Дизајн на внатрешна шема Пред да ги решиме предизвиците, да го дефинираме проблемот и да ги наведеме нашите очекувања за решението: Лесна конверзија на формати потребни од надворешни провајдери и обратно. Потполна поддршка за карактеристики специфични за нашите деловни и податоци науката тимови. Обезбедете дека шемата лесно може да се прошири за да ги задоволи идните барања. Почнавме со преглед на главните LLM шеми за да разбереме како провајдерите ги структурираат пораките, параметрите и излезите. заеднички во повеќето системи, вклучувајќи: core domain entities Пораки (на пример, веднаш, историја) Параметри за генерирање (на пример, температура, top_p, beam_search) Постојат одредени параметри, како што се: , на или , како специфични за внатрешната конфигурација на провајдерот и деловната логика. Овие елементи лежат надвор од основниот домен на LLM и не се дел од заедничката шема. Наместо тоа, тие се третираат како опционални екстензии. Секогаш кога функцијата станува широко прифатена или неопходна за поширока интероперабилност, ние ја оценуваме интеграцијата во основната шема. service_tier usage_metadata reasoning_mode На високо ниво, нашата шема за влез е структурирана со овие клучни компоненти: Се користи како клуч за рутирање, делува како идентификатор за рутирање, овозможувајќи му на системот да го насочи барањето до соодветниот работен јазол. Параметри за генерирање — Поставувања на моделот на јадрото (на пример, температура, top_p, max_tokens). Пораки – историја на разговори и брзи надоместоци. Инструменти – Дефиниции на алатките што може да ги користи моделот. Ова нè доведува до следнава шема, претставена во Тоа ја илустрира структурата и намерата на дизајнот, иако некои детали за имплементација се пропуштаат за едноставност. Питански како Питански како class ChatCompletionRequest(BaseModel): model: str # Routing key to select the appropriate model or service messages: list[Message] # Prompt and dialogue history generation_parameters: GenerationParameters # Core generation settings tools: list[Tool] # Optional tool defenitions class GenerationParameters(BaseModel): temperature: float top_p: float max_tokens: int beam_search: BeamSearchParams # Optional, non-core fields specific to certain providers provider_extensions: dict[str, Any] = {} ... # Other parameters Ние намерно ги преместивме параметрите за генерирање во одделно вградено поле наместо да ги поставиме на ниво на коренот. параметри (на пример, температура, врв-p, поставувања на моделот) и Многу тимови во нашиот екосистем ги чуваат овие константи во надворешните системи за конфигурација, што го прави ова одвојување практично и неопходно. константна Варијанти Ние вклучуваме дополнително поле наречено Во рамките на Овие параметри значително се разликуваат низ различни LLM провајдери, валидација и толкување на овие полиња е - компонента која знае како да комуницира со одреден провајдер на модел. На тој начин, го избегнуваме непотребното спојување преку пренос предизвикани од вишокот на валидација на податоците во повеќе услуги. provider_extensions GenerationParameters delegated to the final module that handles model inference За да се обезбеди обратно компатибилност, се воведуваат нови карактеристики на шемата за излез како: во шемата на барањето. Овие полиња делуваат како знамиња на карактеристики – корисниците мора да ги постават за да се одлучат за одредени однесувања. Овој пристап го задржува основниот шема стабилен додека овозможува концентрична еволуција. На пример, трагите на размислување ќе бидат вклучени во излезот само ако соодветното поле е поставено во барањето. explicit, optional fields Овие шеми се одржуваат во заедничка библиотека на Python и се користат низ услугите за да се обезбеди конзистентно обработка на барањето и одговорот. Работа со трети лица провајдери Почнавме со опишување на тоа како ја изградивме нашата сопствена платформа – па зошто да се грижиме за компатибилност меѓу надворешните провајдери? Синтетичко генерирање на податоци за прототипирање и експериментирање од страна на нашите тимови за податоци. Задачи со општа намена каде што некои сопствени модели се изведуваат подобро надвор од кутијата. Нечувствителни случаи на употреба каде што приватноста, латентноста или контролата на инфраструктурата се помалку критични. Целокупниот комуникациски тек со надворешните провајдери може да се сумира како што следува: Овој процес вклучува следниве чекори: Специјална услуга LLM-Gateway одговорен за комуникација со провајдерот добива барање на корисникот во нашиот шема-формат. Барањето се конвертира во формат специфичен за провајдерот, вклучувајќи ги и сите обезбеди_екстензии. Надворешниот провајдер го обработува барањето и враќа одговор. Службата LLM-Gateway го прима одговорот и го мапира назад во нашата стандардизирана шема за одговор. Ова е шема на високо ниво која ги апстрахира некои од поединечните микро-услуги. Детали за специфични компоненти и формат за одговор на стриминг ќе бидат опфатени во следниве делови. Стриинг формат Одговорите на LLM се генерираат постепено - токен по токен - а потоа се агрегираат во Од гледна точка на корисникот, без разлика дали преку прелистувач, мобилна апликација или терминал, искуството мора да остане За тоа е потребен механизам за транспорт кој го поддржува . chunks fluid and responsive low-latency, real-time streaming Постојат две главни опции за постигнување на ова: WebSockets: Целосно дуплексен комуникациски канал кој овозможува континуирана двонасочна интеракција помеѓу клиентот и серверот. Настани испратени од серверот (SSE): Еднонасочен протокол за стриминг базиран на HTTP кој се користи широко за ажурирања во реално време. Вебсоцет Вебсоцет Серверот испраќа настани (SSE) Серверот испраќа настани (SSE) Зошто SSE над WebSockets? Додека двете опции се изводливи, — особено за OpenAI компатибилни API и слични системи. Ова се должи на неколку практични предности: SSE is the more commonly used solution for standard LLM inference Едноставност: SSE работи над стандардниот HTTP, не бара посебни надградби или преговори. Компатибилност: Работи природно во сите главни прелистувачи без дополнителни библиотеки. Еднонасочен тек: Повеќето одговори на LLM течат само од сервер до клиент, што е во согласност со дизајнот на SSE. Proxy-Friendliness: SSE игра добро со стандардната HTTP инфраструктура, вклучувајќи ги и обратните прокси. Надградби или преговори Поради овие придобивки, . SSE is typically chosen for text-only, prompt-response streaming use cases Сепак, некои нови случаи на употреба бараат побогати, ниско-латентни, двонасочни комуникации - како што се транскрипција во реално време или интеракции на говор до говор. ги задоволува овие потреби со користење на Овие протоколи се подобро прилагодени за континуиран мултимодален влез и излез. API за реално време на OpenAI WebSockets API за реално време на OpenAI Бидејќи нашиот систем се фокусира исклучиво на Ние се држиме со за неговата едноставност, компатибилност и усогласеност со нашиот модел за стриминг. text-based interactions SSE Реакција Stream Содржина со избрани како транспортниот слој, следниот чекор беше да се дефинира Ефективниот стриминг бара повеќе од само суров текст – треба да обезбеди доволно за поддршка на потрошувачите надолу, како што се корисничките интерфејси и алатките за автоматизација. SSE what structure, metadata, and context Basic identifying information such as request ID. Header-Level Metadata. Всушност содржината Chunks. Основниот излез - токените или низа генерирани од страна на моделот - се испорачува постепено како секвенци (n) се пренесуваат назад, дел по дел. Секоја генерација може да се состои од повеќе секвенци (на пример, n = 2, n = 4) .Овие секвенци се генерираат независно и се пренесуваат паралелно, секоја поделена во свој сет на концентрични парчиња. Користење и метаподатоци на ниво на токен. Ова вклучува број на генерирани токени, податоци за времето и опционална дијагностика како што се logprobs или расудување траги. По дефинирањето на структурата на одговорот што се емитува, исто така, разгледавме неколку нефункционални барања кои се од суштинско значење за сигурност и иднина. Нашиот дизајн на потокот е наменет да биде: Структурирано – јасно разликувајќи ги типовите на содржина и границите на настаните. Екстензибилен – способен да носи опционални метаподатоци без да ги скрши постоечките клиенти. Робусен – отпорен на погрешно формирани, одложени или парцијални податоци. Во многу апликации, како што се или - повеќе секвенци (завршувања) се генерираат паралелно како дел од едно генерациско барање. side-by-side comparison diverse sampling Најширокиот формат за стриминг одговори е дефиниран во Според спецификацијата, едно генерациско парче може да вклучува повеќе секвенци во Арсенал : OpenAI API референца choices OpenAI API референца Изборот Арсенал Листа на опции за завршување на разговор. Може да содржи повеќе од еден елемент ако n е поголем од 1. choices array Листа на опции за завршување на разговор. Може да содржи повеќе од еден елемент ако n е поголем од 1. Иако, во пракса, поединечните парчиња обично содржат само една делта, форматот овозможува повеќе ажурирања на секвенца по парче.Важно е да се земе предвид ова, бидејќи идните ажурирања може да ја искористат оваа способност пошироко. се дизајнирани да ја поддржат оваа структура. Официјален Python SDK Официјален Python SDK Ние избравме да ја следиме истата структура за да обезбедиме компатибилност со широк спектар на потенцијални карактеристики. Дијаграмот подолу илустрира пример од нашата имплементација, каде што една генерација се состои од три секвенци, пренесувани во шест парчиња со текот на времето: Овој дел го означува почетокот на целата генерација. Тој не содржи никаква вистинска содржина, но вклучува споделени метаподатоци, како што се идентитетот на генерацијата, временската ознака и улогата (на пример, асистент, итн.). Two sequences begin streaming in parallel. Each is tagged with a unique identifier to distinguish it from others. Chunk 2 — Sequence Start (Green & Purple). Третата секвенца започнува (сина), додека првите две секвенци (зелена и пурпурна) пренесуваат концентрирана содржина преку делта настани. Chunk 4 – Midstream Updates & Finish (Пурпур). Зелените и сините секвенци продолжуваат да ги пренесуваат делтата. Пурпурната секвенца завршува – ова вклучува структурирана причина за завршување (како што е запирање, должина итн.). Част 5 – Останува секвенца Завршува. И зелените и сините секвенци се завршени. Животниот циклус на секоја секвенца сега е целосно заклучен помеѓу нејзините соодветни маркери за почеток и крај. Овој дел ја затвора генерацијата и може да вклучува глобална статистика за користење, конечни броеви на токени, информации за задоцнување или друга дијагностика. Како што можете да видите, за да го направите потокот цврст и полесен за анализирање, одлучивме да , наместо да се потпира на имплицитни механизми како што се нул проверки, EOFs, или магични токени. Овој структуриран пристап го поедноставува доследното анализирање, особено во средини каде што повеќе завршувања се пренесуваат паралелно, а исто така ја подобрува дебугабилноста и изолацијата на грешките за време на развојот и инспекцијата на времетраењето. explicitly signal Start and Finish events for both the overall generation and each individual sequence Покрај тоа, воведуваме дополнителни chunk that carries structured information about failures. Some errors — such as malformed requests or authorization issues — can be surfaced directly via standard HTTP response codes. However, if an error occurs , we have two options: either abruptly terminate the HTTP stream or emit a well-formed SSE error event. We chose the latter. Abruptly closing the connection makes it hard for clients to distinguish between network issues and actual model/service failures. By using a dedicated error chunk, we enable more reliable detection and propagation of issues during streaming. Error during the generation process Backend Services and Request Flow Во центарот на системот е една влезна точка: . It handles basic concerns like authentication, usage tracking and quota enforcement, request formatting, and routing based on the specified model. While it may look like the Gateway carries a lot of responsibility, each task is intentionally simple and modular. For external providers, it adapts requests to their APIs and maps responses back into a unified format. For self-hosted models, requests are routed directly to internal systems using our own unified schema. This design allows seamless support for both external and internal models through a consistent interface. LLM-Gateway Самостојни модели Како што споменавме порано, is well-suited for streaming responses to end users, but it’s not a practical choice for Кога ќе пристигне барање, тоа мора да биде пренасочено до соодветен работен јазол за заклучување на моделот, а резултатот се пренесува назад.Додека некои системи се справуваат со ова со користење на синџирирани HTTP прокси и рутирање врз основа на наслов, во нашето искуство, овој пристап станува тешко да се управува и да се развива како логиката расте во комплексност. Server-Sent Events (SSE) internal backend communication Нашата внатрешна инфраструктура треба да го поддржи: Планирање со свест за приоритети – Барањата може да имаат различни нивоа на итност (на пример, интерактивни против партици), а задачите со висок приоритет мора прво да се справат. — Certain nodes run on higher-performance GPUs and should be preferred; others serve as overflow capacity. Hardware-aware routing — Each worker is configured to support only a subset of models, based on hardware compatibility and resource constraints. Model-specific dispatching To address these requirements, we use a to decouple task routing from result delivery. This design provides better flexibility and resilience under varying load and routing conditions. We use за оваа намена, иако други брокери, исто така, може да бидат одржливи во зависност од вашата латенција, промет и оперативни преференции. RabbitMQ беше природно прилагодување со оглед на неговата зрелост и усогласување со нашите постоечки алатки. message broker RabbitMQ RabbitMQ Зајакот Сега, ајде да погледнеме поблиску како овој систем се имплементира во пракса: Ние користиме , allowing us to route requests based on model compatibility and node capabilities. The process is as follows: dedicated queues per model Службата LLM-Gateway (представена како корисник) иницира HTTP барање за да предизвика задача за генерирање на текст. Забавата се обработува од страна на Планер, кој го избира соодветниот ред (означен со зелена боја на сликата) врз основа на побараниот модел и ја прикачува пораката на него. An appropriate (only one worker is shown for simplicity, but there are many) subscribed to the queue picks up the task and begins processing. This worker runs the selected model locally. Worker Picks Up Task. Inference Worker The worker streams the response chunk-by-chunk into the , to which the . Streaming the Response. Response Queue Scheduler replica handling the request is subscribed Планирачот го слуша редот за одговори и ги прима парчињата за одговори како што пристигнуваат. The chunks are converted to SSE format and streamed to the client. SSE Streaming. да се однесуваат , ние се избегнува преоптоварување на пораката брокер: large payloads Наместо да вградуваме големи податоци за влез или излез директно во задачата, ние ги пренесуваме во надворешна S3 компатибилна продавница. Референца (како што е URL или ИД на ресурс) е вклучена во метаподатоците на задачата, а работникот ја презема вистинската содржина кога е потребно. Примена на дизајнот со RabbitMQ When it comes to Секое е редовна RabbitMQ , посветен на ракување со еден модел тип. што може да се постигне со користење на . In this setup, messages with higher priority values are delivered and processed before lower priority ones. For , каде што пораките прво треба да бидат насочени кон најмоќните достапни јазли, Потрошувачите со повисок приоритет примаат пораки додека се активни; потрошувачите со понизок приоритет примаат пораки само кога пораките со повисок приоритет се блокирани или не се достапни. routing and publishing messages Request Queue опашка priority-aware scheduling message priorities hardware-aware routing Приоритети на потрошувачите опашка message priorities Приоритети на потрошувачите Ако загубата на пораката е неприфатлива, следново мора да биде на место: to ensure the broker has received and stored the message. Publisher confirms Трајни редици и упорни пораки за да може податоците да преживеат. Quorum редови за посилна издржливост преку репликација.Овие, исто така, поддржуваат поедноставена порака и потрошувачки приоритети од RabbitMQ 4.0. Publisher confirms Publisher confirms Кворум на чекори Кворум на чекори поедноставена порака и приоритети на потрошувачите од RabbitMQ 4.0 Досега, покривме како се објавуваат задачите - но како е handled? The first step is to understand how работа во RabbitMQ. брокерот поддржува концепт наречен , which are bound to a single connection and automatically deleted when that connection closes. This makes them a natural fit for our setup. streamed response temporary queues Ексклузивни чекори Ексклузивни чекори Ексклузивни чекори We create Сепак, ова воведува предизвик: додека секоја сервисна реплика има еден RabbitMQ ред, мора да се справи . one exclusive queue per Scheduler service replica many requests in parallel За да го решиме ова, го третираме редот RabbitMQ како , routing responses to the correct Scheduler replica. Each user request is assigned a , which is included in every response chunk. Inside the Ние го одржуваме дополнителниот со краткотрајни редови во меморијата – еден по активна барање. Доаѓачките редови се споредуваат со овие редови врз основа на идентификаторот и се пренесуваат соодветно. Овие редови во меморијата се отфрлаат откако барањето е завршено, додека редот RabbitMQ трае за време на животот на репликата на услугата. transport layer unique identifier Scheduler in-memory routing layer Схематски ова изгледа како што следува: Централниот диспечер во распоредувачот испраќа парчиња до соодветниот ред во меморијата, секој управуван од посветен манипулатор. Заклучокот Постојат неколку зрели рамки на располагање за ефикасна LLM заклучоци, како што се: и Овие системи се дизајнирани за and generate response tokens in real time, often with features like continuous batching and GPU memory optimization. In our setup, we use како јадро на моторот за заклучување, со неколку сопствени модификации: Влм Согласување process multiple sequences in parallel vLLM Влм Влм SGLANG Согласување Прилагодена имплементација на пребарување на зраци – за подобро да се вклопи во нашата логика за генерација и да ги поддржи структурираните ограничувања. Поддршка за структурирани шеми за излез – овозможувајќи им на моделите да враќаат излез во согласност со формати специфични за бизнисот. Преку искуство, научивме дека дури и мали ажурирања на библиотеката може да - без разлика дали во квалитетот на излезот, детерминизмот или современото однесување. Поради ова, имаме воспоставено силна тест цевка: significantly alter model behavior Тестирање на стрес за откривање на проблеми со истовремена работа, фрлање на меморијата или регресија на стабилноста. to ensure consistent outputs for fixed seeds and parameter sets. Determinism testing Тестирање на параметарската мрежа за покривање на широк спектар на поставувања за генерација, без да се преоптоварува. Складирање и распоредување Повеќето современи системи работат во – или во облакот или во Kubernetes (K8s). Додека оваа конфигурација работи добро за типични услуги за поддршка, воведува предизвици околу . LLM models can be , и моделот за печење тежи директно во сликите на Docker - брзо станува проблематичен: containerized environments model weight storage tens or even hundreds of gigabytes in size Бавно градење – Дури и со повеќефазни градења и кеширање, преносот на големи датотеки на модели за време на фазата на градење може драматично да го зголеми времето на CI. — Each rollout requires pulling massive images, which can take several minutes and cause downtime or delays. Slow deployments Неефикасноста на ресурсите – ниту регистрите на Docker, ниту јазлите на Kubernetes не се оптимизирани за обработка на екстремно големи слики, што резултира со надуена употреба на складирањето и оптоварување на опсегот. За да го решиме ова, ние раздвојуваме од животниот циклус на сликата на Docker. Нашите модели се чуваат во , и го зедовме непосредно пред стартувањето на услугата за заклучување. За да го подобриме времето за стартување и да избегнеме вишокот на преземања, исто така користиме за да ги кеширате тежините на моделот на секој јазол. model storage external S3-compatible object storage Локални перзистентни волумени (ПВЦ) Локални перзистентни волумени (ПВЦ) Локални перзистентни волумени (ПВЦ) Observability A system like this — built on Потребно е за да се обезбеди сигурност и перформанси на скала. streaming, message queues, and real-time token generation robust observability Во прилог на стандардните метрики на ниво на услуга (CPU, меморија, стапки на грешка, итн.), сметавме дека е од суштинско значење да се следи следново: Длабочината на редот, задржувањето на пораките и бројот на потрошувачи – следењето на бројот на непотребни пораки, тековната големина на редот и бројот на активни потрошувачи помага да се откријат пречки во дистрибуцијата на задачите и нерамнотежи во искористувањето на работниците. Token/chunk throughput – следење на бројот на токени или одговорни парчиња генерирани во секунда помага да се идентификуваат регресиите на латенција или пропуск. Дистрибуирано следење – за да се утврди каде барањата не успеваат или се заглавуваат низ компоненти (gateway, брокер, работници, итн.). Проверка на здравјето на моторот - бидејќи процесите на заклучување може да се урнат под ретки услови (на пример, лош влез или екстремни вредности на параметрите), проактивно следење на жизненоста и подготвеноста е критично. Дистрибуиран трасинг Дистрибуиран трасинг Further Improvements Додека нашиот систем е подготвен за производство, се уште постојат важни предизвици и можности за оптимизација: Користење на дистрибуиран КВ кеш за да се зголеми перформансите на заклучување. Поддршка за откажување на барање за зачувување на компјутерите кога излезот повеќе не е потребен. Креирање на едноставен модел за испорака на цевката за тимовите за наука за податоци. Заклучок Додека изградбата на сигурен и независен од провајдерот LLM сервисинг систем може да изгледа комплицирано на почетокот, тоа не бара повторно да се измислува тркалото. Секоја компонента - стриминг преку SSE, дистрибуција на задачи преку брокери за пораки и заклучоци обработени со времетраење како vLLM - служи јасна цел и е зацврстена во постоечките, добро поддржани алатки. Во следната статија, ќе ги истражуваме повеќе напредни теми како што се дистрибуираното КВ-цаширање, ракувањето со повеќе модели низ реплики и работите за имплементација погодни за ML-ориентирани тимови. авторите Точка , Станислав Шимолос Станислав Шимолос Станислав Шимолос Точка , Максим Афанасиев Максим Афанасиев Maxim Afanasyev Признанија Работи направени во Точка Дмитриј Криуков Дмитриј Криуков Дмитриј Криуков