Bỏ qua đến nội dung chính

The Small Model Infrastructure Nobody Built (So We Did) — Filip Makraduli, Superlinked

TL;DR

  • Inference cho các mô hình AI nhỏ thường bị bỏ qua nhưng lại rất quan trọng để giải quyết vấn đề context rot trong AI searchdocument processing.
  • Các giải pháp inference truyền thống không hiệu quả với mô hình nhỏ; cần tối ưu hóa việc sử dụng GPU thông qua hot-swapping và hỗ trợ toàn diện cơ sở hạ tầng để triển khai production.
  • Superlinked inference engine (Sie) là một giải pháp mã nguồn mở, end-to-end giúp giải quyết những thách thức này bằng cách hỗ trợ đa dạng mô hình và cung cấp cluster support mạnh mẽ.

Inference request

Superlinked Inference Engine

Hot-swap models on GPU

Cluster support — multi-node

Low-latency response

Điểm chính

  • Hiểu và tối ưu hóa inference cho các mô hình nhỏ là rất quan trọng để quản lý ngữ cảnh và chống lại context rot trong các workflow của tác nhân.
  • Các mô hình nhỏ có thể được sử dụng hiệu quả cho preprocessing dữ liệu, tool callingcontext management, giúp giảm lượng mã thông báo cần thiết cho các tác nhân lớn.
  • Việc chỉ định một GPU riêng cho mỗi mô hình nhỏ là lãng phí tài nguyên; cần có khả năng hot-swap các mô hình trên cùng một GPU và triển khai chính sách least recently used eviction để tối đa hóa hiệu suất.
  • Một giải pháp inference đầy đủ cho production cần tích hợp routing, auto-scaling, queuing mechanisms, monitoring (với Prometheus metricsGrafana), và GPU provisioning tự động.
  • Hỗ trợ mô hình đa dạng, đặc biệt là các mô hình mã nguồn mở, đòi hỏi phải re-implement hoặc điều chỉnh forward pass để xử lý các kiến trúc khác nhau (ví dụ: flash attention, positional embeddings).
  • Tối ưu hóa inference cần tính đến variable length attention và cơ chế padding thông minh để tránh lãng phí compute trên các mã thông báo trống khi thực hiện token-based batching.
  • Sie cung cấp một nền tảng mã nguồn mở end-to-end bao gồm cả model inference được điều chỉnh (như forward pass tùy chỉnh) và cluster quản lý, có sẵn dưới dạng Helm chartsDocker images để triển khai dễ dàng.

Từ vựng

  • Inference — Suy luận/Chạy suy luận mô hình
  • Context Rot — Suy giảm ngữ cảnh
  • Open-source — Mã nguồn mở
  • Infrastructure — Cơ sở hạ tầng
  • Model — Mô hình
  • Flash Attention — Flash Attention (một kỹ thuật tối ưu hóa cơ chế chú ý)
  • Positional Embeddings — Mã hóa vị trí/Phép nhúng vị trí
  • Auto-scaling — Tự động điều chỉnh quy mô
  • Tool calling — Gọi công cụ
  • Forward Pass — Lượt truyền xuôi

Nội dung chi tiết

Giới thiệu và Khám phá vấn đề Inference

Xin chào mọi người. Chào mừng đến với buổi nói chuyện này. Tôi sẽ trình bày về inference của các mô hình nhỏ và một khoảng trống mà chúng tôi đã nhận ra trên thị trường, cũng như những gì chúng tôi đã làm để giải quyết và lý do chúng tôi chọn cách tiếp cận này. Như bạn thấy slide nền ở đây, điều này không phải ngẫu nhiên. Nếu bạn đoán được đây là gì, tôi sẽ đưa ra một lời nhắc ở cuối các slide, bạn sẽ nhận được một phần thưởng nhỏ. Bạn có thể gặp tôi vào giờ giải lao sau đó. Vì vậy, hãy suy nghĩ về điều này, nhưng cũng hãy lắng nghe tôi, đừng suy nghĩ quá nhiều.

Câu chuyện bắt đầu khi tôi đăng một bài viết cách đây vài tháng trên Substack, bài viết này đã thu hút được một chút sự chú ý và khiến một số người quan tâm. Tôi đã giải thích về flash attention, cách các mô hình hoạt động, cách các quy trình có thể bị giới hạn bộ nhớ (memory-bound), giới hạn tính toán (compute-bound), và tôi cảm thấy rất tốt vì tôi đã đi sâu vào vấn đề này. Là một người đã làm việc trong AI vài năm, tôi cảm thấy rất tự tin. Điều đó đúng, nhưng sau đó một số người đã chỉ ra rằng thực ra tôi đã bỏ qua một khía cạnh quan trọng về điều gì làm cho những mô hình này nhanh trong thế giới thực. Và khía cạnh mà tôi đã bỏ qua chính là inference. Là một người muốn hiểu mọi thứ từ nguyên tắc cơ bản và tìm hiểu sâu các vấn đề và giải pháp, tôi nhận ra: "Được rồi, mình cần phải tìm hiểu điều này. Mình cần biết mình đã mắc lỗi ở đâu và với tư cách là một nhà nghiên cứu, kỹ sư AI, mình cần tìm hiểu thêm về inference."

Xây dựng Giải pháp Inference cho Mô hình Nhỏ

Tôi đã làm việc rất nhiều với VLAM, huấn luyện mô hình, fine-tuning, làm MLAI ứng dụng, cũng như nghiên cứu trong giới học thuật. Nhưng phần xung quanh cách các mô hình chạy trong production, scheduling GPUs, routingautomation dường như là một điểm mù đối với tôi. Vì vậy, tôi nhận ra: "Được rồi, đây là lúc mình phải tìm hiểu, học hỏi và biến nó thành hiện thực." Và cách tốt nhất để làm điều này là thực sự xây dựng sản phẩm. Vì vậy, tôi quyết định tham gia một nhóm, một nhóm tại Superlinked, bao gồm các kỹ sư cơ sở hạ tầng rất giỏi, và thực sự làm việc với họ để xây dựng một cái gì đó liên quan đến inference.

Và cái gì đó là repo này, Superlinked inference engine mà chúng tôi đã open-source, và đây là buổi ra mắt mềm mà tôi đang thực hiện hôm nay. Bạn có thể xem nó sau. Về cơ bản, đó là inference cho các mô hình nhỏ xung quanh AI searchdocument processing. Chúng tôi đã thử nghiệm điều này, như bạn có thể thấy, với một số đối tác của chúng tôi. Chúng tôi đã thử nghiệm với Chroma, Quadrant, Weaviate - rất nhiều cơ sở dữ liệu vector (vector DBs), cũng như LanceDB. Và như bạn thấy, họ đã thử nghiệm một chút. Nghe có vẻ vui, có vẻ thú vị. Vì vậy, điều này đang hoạt động. Và đó là bước đi đúng đắn để tôi tìm hiểu và học hỏi xem inference thực sự ở đâu và làm thế nào để kết hợp điều đó với kinh nghiệm ML của tôi.

Ba Điểm Trọng Tâm của Bài Nói Chuyện

Ba điểm chính mà tôi muốn bạn ghi nhớ từ buổi nói chuyện này là:

  1. Tại sao điều này lại quan trọng? Tôi muốn nói với bạn tại sao việc thực hiện inference cho AI searchdocument processing thực sự quan trọng khi bạn đang xây dựng các tác nhân hoặc khi bạn đang xây dựng các workflow liên quan đến tác nhân. Vì vậy, lý do tại sao điều này rất quan trọng.
  2. Inference không phải là gì? Sau đó, tôi muốn nói với bạn về điều thứ hai, đó là inference không phải là gì. Có một số quan niệm sai lầm hoặc ý tưởng về hình thức của inference, nhưng không phải tất cả đều là về những điều đó.
  3. Cách chúng tôi nhìn nhận inference. Và điều thứ ba là cách chúng tôi nhìn nhận inference, tôi gọi đây là "âm và dương của model inference", và đó là một cách kết hợp một vài điều xung quanh model supportinfrastructure.

Tầm Quan trọng của Inference: Giải quyết Context Rot

Tại sao điều này lại quan trọng đối với workflow của tác nhân của bạn? Chắc chắn bạn đã gặp phải tình trạng context rot. Và như chúng ta có thể đều biết, bài nghiên cứu này từ Chroma từ một thời gian trước đã trình bày hiệu ứng này: dù bạn làm gì đi chăng nữa, đều có hiệu ứng context rot. Nghĩa là, chất lượng giảm đi khi ngữ cảnh tăng lên. Vì vậy, việc có thể quản lý ngữ cảnh này và thực hiện một số context management là rất quan trọng và là một cách hữu ích để giải quyết vấn đề này.

Việc sử dụng các mô hình nhỏ có thể preprocess dữ liệu của bạn để sau đó bạn có thể thực sự sử dụng các tác nhân và xây dựng workflow của mình là một kỹ thuật rất mạnh mẽ. Bạn cũng có thể sử dụng các mô hình nhỏ để tool calling để lại thực hiện những việc tương tự và giải quyết vấn đề context management này. Và bạn có thể nói, "Được rồi, tại sao tôi không sử dụng codegrepping?" Và đó là một điểm hợp lý. Tuy nhiên, bạn vẫn có thể làm điều đó và việc preprocess dữ liệu của bạn thực sự làm cho grepping và các file system mà bạn xây dựng thậm chí còn tốt hơn.

Phản hồi của Cộng đồng và Ứng dụng Thực tế

Và không chỉ tôi nói điều này, đây là cách cộng đồng đã phản ứng với vấn đề này. Andrej Karpathy đang xây dựng các cơ sở tri thức (knowledge bases) dựa trên đồ thị. Ví dụ, bạn có thể sử dụng các mô hình nhận dạng thực thể có tên (named entity recognition models) để tạo bản thể luận (ontologies) và sau đó xây dựng đồ thị tri thức (knowledge graphs) hoặc bạn tạo các file system của mình theo cách đó. Chroma cũng đã phát hành mô hình riêng của họ thực hiện điều này. Nó preprocessfilter input, manage context để giải quyết và đạt được cùng một vấn đề. Và cũng có những người trong cộng đồng đang xây dựng rất nhiều giải pháp giúp giảm ngữ cảnh này và giảm lượng mã thông báo (token) để các tác nhân có thể hiệu quả hơn nữa.

Và chúng tôi cũng đã làm điều này trong production. Chúng tôi có một trường hợp sử dụng nơi repo mà tôi đã giới thiệu, Superlinked inference engine, chúng tôi đã sử dụng nó như một giải pháp tool calling, về cơ bản, là phân loại taxonomy classification cho một cửa hàng thương mại điện tử. Vì vậy, việc đi trực tiếp với tool calling nơi các mô hình nhỏ là các công cụ có thể truy xuất và xem xét dữ liệu của bạn cũng là một cách tiếp cận mạnh mẽ.

Điều Gì Không Phải Là Inference: Hiệu quả GPU cho Mô hình Nhỏ

Bây giờ tôi sẽ nói về inference và những gì inference không giống. Có lẽ quan điểm truyền thống là, "Được rồi, tôi sẽ chỉ thêm nhiều GPU, có thêm compute, mọi thứ đều tốt, tôi đã giải quyết được inference." Tuy nhiên, với các mô hình nhỏ, nơi thực sự mỗi mô hình chỉ chiếm một không gian nhỏ trong bộ nhớ. Ví dụ, bạn có thể thấy Stella, là một embedding model, sau đó là các reranker khác, mô hình NER Glyner, chúng chỉ chiếm vài gigabyte bộ nhớ. Và nếu bạn cấp phát một GPU cho mỗi mô hình, bạn đang lãng phí rất nhiều idle space. GPU của bạn vẫn nhàn rỗi và không được sử dụng. Vì vậy, trong trường hợp inference của mô hình nhỏ, điều rất quan trọng là có thể hot-swap các mô hình.

Vì vậy, những gì chúng tôi đã làm là chúng tôi đã xây dựng khả năng cho bạn để swap tất cả các mô hình này trong một GPU duy nhất để mỗi GPU, bạn có được mức sử dụng cao hơn nhiều. Điều này làm giảm chi phí của bạn, nhưng cũng cho phép bạn hot-swap và chuyển đổi giữa các mô hình một cách nhanh chóng. Nếu bạn muốn có một công cụ là một reranker hoặc một công cụ khác là một mô hình khác, bạn có thể chuyển đổi chúng một cách nhanh chóng, và chúng tôi đã xây dựng chính sách least recently used eviction vào đó.

Điều Gì Không Phải Là Inference: Từ Phát triển đến Production

Và điều mà inference không phải là, chỉ là máy chủ hoặc chỉ là tình huống production. Vì vậy, chúng tôi có các giải pháp cho cả máy chủproduction, nhưng việc xây dựng một cái gì đó, ví dụ như sử dụng Tay hoặc VLAM hoặc thậm chí có một API wrapper để đưa nó vào production nơi bạn thực sự thực hiện routing, auto-scaling, bạn thực hiện monitoring với Prometheus metricsGrafana, bạn phải tự viết code đó. Và trên thị trường hiện tại, không có giải pháp mã nguồn mở nào dẫn bạn từ việc tạo model inference đến việc đưa vào sản xuất (productionizing) điều này ở quy mô như vậy.

Đó là lý do tại sao chúng tôi cũng muốn lấp đầy khoảng trống này. Vì vậy, chúng tôi đã bao gồm rất nhiều thứ xung quanh routing, auto-scaling, queuing mechanismsprovisioning GPUs. Tôi đã nói về những gì inference không phải là, tại sao điều này lại quan trọng, và bây giờ hãy để tôi nói với bạn về những gì inference thực sự là. Và tôi gọi đây là âm và dương của inference bởi vì tôi cảm thấy đây là một cách tiếp cận toàn diện phải kết hợp hai điều quan trọng.

Âm (Yin): Hỗ trợ Đa dạng Mô hình

Thứ nhất, âm là model support. Inference của bạn vô giá trị nếu bạn không hỗ trợ đúng mô hình hoặc bạn không cung cấp đủ sự đa dạng về các tùy chọn cho người dùng của mình. Và các mô hình mã nguồn mở (open source models), hiện tại trên Hugging Face có hàng triệu mô hình. Đây là số liệu từ tháng 3. Bây giờ, có thể còn nhiều hơn, gần 3 triệu mô hình. Và mã nguồn mở đang phát triển rất nhanh cả về kích thước lẫn độ chính xác (accuracy). Vì vậy, bạn cần phải hỗ trợ những mô hình này vì mọi người muốn sử dụng chúng. Mọi người muốn làm việc với mã nguồn mở, và hiệu suất (performance) cũng ngày càng tốt hơn. Vì vậy, nó không còn là sự hy sinh nữa. Thực ra, bạn có thể đối với các tác vụ cụ thể. Nếu bạn nhìn vào MTEB hoặc các benchmark khác, bạn có thể thấy rằng đối với các tác vụ rất chuyên biệt, các mô hình mã nguồn mở đang vượt trội so với các dịch vụ được quản lý (managed services). Và chúng ta thấy điều này ngay cả với các mô hình đa năng hơn như những gì Gemma đã làm. Vì vậy, họ đã phát hành các mô hình có ít tham số (parameter) hơn nhưng có ELO scores cao hơn nhiều so với các mô hình lớn hơn rất nhiều. Vì vậy, các mô hình nhỏ mã nguồn mở rất phù hợp, và bạn cần cơ sở hạ tầng (infra) để hỗ trợ chúng.

Thách thức trong Hỗ trợ Mô hình Đa dạng

Chúng tôi quyết định làm chính xác điều này. "Được rồi, hãy làm đi. Chúng ta sẽ xây dựng và hỗ trợ hàng trăm mô hình." Tuy nhiên, điều đó không đơn giản như bạn nghĩ bởi vì tất cả các mô hình này đều có các runtime khác nhau. Ví dụ, nếu bạn sử dụng BERTQwen làm mô hình, chúng có các triển khai flash attention khác nhau. Chúng có các positional embeddings khác nhau, và bạn cần điều chỉnh điều này để làm cho nó áp dụng được cho trường hợp của bạn và làm cho nó tổng quát hơn.

Vì vậy, không có engine nào có thể xử lý BERT, QwenBERT hiện đại vì kiến trúc của chúng khác nhau. Vậy chúng tôi đã làm gì là thiết lập một cách để re-implement forward pass để điều chỉnh attention, để thực hiện padding khi cần thiết, vì vậy cũng có variable length attention. Làm việc với việc hợp nhất (fusion) của query, keyvalue. Và đây là một thành phần bị đánh giá thấp, đặc biệt nếu bạn nhìn vào việc hỗ trợ các mô hình như ColBERT có nhiều vector làm đầu ra. Vì vậy, các mô hình tương tác trễ (late interaction models), cũng như cross encodersre-ranker không xuất ra vector nào cả, mà chúng xuất ra các điểm số (scores). Vì vậy, việc tìm ra điều này rất quan trọng, và một ví dụ về điều này là, ví dụ, đây là so sánh của một vài mô hình hoàn toàn khác nhau ở năm khía cạnh này.

Tối ưu hóa Inference qua Xử lý Kiến trúc Mô hình Riêng biệt

Việc chuẩn hóa (normalization) được thực hiện khác nhau trong BERTQwen. Vì vậy, điều đó cần được tính đến. Trong ColBERT, nó cũng hoàn toàn khác. Query, keyvalue cũng có thể được hợp nhất ở một số nơi. Ở những mô hình khác, ví dụ, trong Qwen, nó không thể vì có grouped query attention. Vì vậy, đó là một vấn đề khác. Các positional embeddings cũng khác nhau. Bạn có thể thực hiện absolute lookup trong BERT, trong khi với Qwen, có rotary positional embeddings. Vì vậy, đây là những vấn đề mà có thể mọi người không nghĩ đến ngay lập tức, nhưng nếu bạn muốn hỗ trợ nhiều mô hình, cần phải có một cách nhất quán để làm điều này.

Vì vậy, chúng tôi đã thiết lập điều này bằng cách làm việc với các tác nhân cũng như với con người để có thể hỗ trợ điều này và re-implement forward pass này để làm cho inference của các mô hình này hiệu quả, và chúng tôi cũng đã làm việc để thực hiện flash attention khi đó là variable length flash attention, để bạn có thể thực hiện padding, và không có sự lãng phí bởi vì điều gì xảy ra là nếu bạn muốn thực hiện token-based batching, bạn có thể có các mã thông báo có số lượng mã thông báo thấp hơn trong một yêu cầu, và sau đó một yêu cầu khác là số lượng cao hơn, và sau đó nếu cả hai đều được padding ở số lượng cao hơn, bạn về cơ bản đang lãng phí compute trên các mã thông báo trống. Vì vậy, bạn cần điều chỉnh điều này để làm cho các mô hình hoạt động tốt hơn và nhanh hơn. Và đó là một điểm khác biệt chính trong cách tiếp cận inference của chúng tôi.

Dương (Yang): Tầng Cơ sở hạ tầng

Phần còn lại, dương, là về cơ sở hạ tầng. Đây là biểu đồ phức tạp. Đây là phần đi sâu. Chúng tôi có nó trên trang web và trong repo của chúng tôi. Tôi sẽ không đi sâu vào từng thành phần ở đây, nhưng về cơ bản những gì có ở đó là ba nguyên thủy (primitives) của API của chúng tôi: encode, scoreextract. Và sau đó lớp cơ sở hạ tầng hoạt động, và đây là tóm tắt của nó.

Quản lý Cơ sở hạ tầng và Tối ưu hóa Mô hình

Về cơ bản, chúng tôi có ba nguyên thủy của API, sau đó là một bộ định tuyến (router) và cơ chế hàng đợi (queuing mechanism) tùy thuộc vào tải. Chúng tôi điều chỉnh giữa các yếu tố này, cũng như các nhóm GPU và tài nguyên khác nhau mà chúng tôi sử dụng để phân phối khối lượng công việc. Chúng tôi sử dụng các phiên bản spot (spot instances), nhưng cũng có các GPU lớn hơn. Điều quan trọng ở đây là khả năng cấp phát phần cứng (provision the hardware) và có các số liệu (metrics) để tự động điều chỉnh quy mô (auto scale) nó. Chúng tôi sử dụng KEDA auto scaling với các số liệu Prometheus để có thể chuyển đổi các mô hình xung quanh, tránh để GPU nhàn rỗi và lãng phí tài nguyên.

Mục tiêu chính ở đây là chúng tôi muốn bạn có cả hỗ trợ cluster lẫn mô hình. Không chỉ một trong hai, rồi bạn phải tự mình kết hợp chúng và viết tất cả mã nguồn đó. Thay vào đó, chúng tôi muốn cung cấp cho bạn toàn bộ quy trình từ đầu đến cuối (end-to-end) để bạn có thể làm việc với các mô hình này một cách nhanh chóng. Các mô hình về cơ bản chỉ là một cấu hình (config) mà bạn có thể chuyển đổi và sau đó thực hiện Terraform apply, thế là xong. Chúng tôi cũng đã phát hành các Helm chartsDocker images.

Ra mắt Sie: Giải pháp mã nguồn mở cho Suy luận Mô hình và Cụm

Đây là cách chúng tôi đã học được bài học của mình và xây dựng Sie. Đây là một dạng ra mắt thử nghiệm (soft launch) của chúng tôi. Chúng tôi đã mở mã nguồn (open source) cả phần suy luận mô hình (model inference) mà tôi đã nói, bao gồm việc điều chỉnh forward pass, làm việc với cơ chế attention, triển khai lại các khía cạnh khác nhau trên mô hình, và cả cluster nữa. Điều này giúp bạn có thể sử dụng ngay lập tức mà không cần phải lo lắng về phần cứng, cấp phát GPU và tất cả những vấn đề phát sinh trong thế giới thực. Bạn có thể quét mã QR để xem kho lưu trữ (repo), nó có tên là Sie (S I E) từ công ty Superlinked.

Giải thích Mã hóa Vị trí trong Transformer

(Sau khi người trình bày hỏi khán giả về hình nền)

Vâng, tôi sẽ coi đó là một câu trả lời chính xác. Nó liên quan đến mã hóa vị trí (positional encodings), và vâng, đây về cơ bản là… Chúc mừng! Vậy đây là trực quan hóa vector (vector visualization) của mã hóa vị trí. Việc này được thực hiện khi các kiến trúc Transformer được huấn luyện; đây là cách các vị trí được mã hóa, và nó có dạng hình sin (sinusoidal). Đó là lý do tại sao bạn thấy mẫu hình này, bởi vì chúng là các phép nhúng (embeddings). Cảm ơn rất nhiều.

Góp ý / Báo lỗiPhát hiện sai sót hoặc có ý tưởng cải thiện?