Inferencecho cácmô hìnhAI nhỏ thường bị bỏ qua nhưng lại rất quan trọng để giải quyết vấn đềcontext rottrongAI searchvàdocument processing.- Các giải pháp
inferencetruyền thống không hiệu quả vớimô hìnhnhỏ; cần tối ưu hóa việc sử dụngGPUthông quahot-swappingvà hỗ trợ toàn diệncơ sở hạ tầngđể triển khaiproduction. Superlinked inference engine(Sie) là một giải phápmã nguồn mở,end-to-endgiúp giải quyết những thách thức này bằng cách hỗ trợ đa dạngmô hìnhvà cung cấpcluster supportmạnh mẽ.
The Small Model Infrastructure Nobody Built (So We Did) — Filip Makraduli, Superlinked
- Hiểu và tối ưu hóa
inferencecho cácmô hìnhnhỏ là rất quan trọng để quản lýngữ cảnhvà chống lạicontext rottrong cácworkflowcủatác nhân. - Các
mô hìnhnhỏ có thể được sử dụng hiệu quả chopreprocessingdữ liệu,tool callingvàcontext management, giúp giảm lượngmã thông báocần thiết cho cáctác nhânlớn. - Việc chỉ định một
GPUriêng cho mỗimô hìnhnhỏ là lãng phí tài nguyên; cần có khả nănghot-swapcácmô hìnhtrên cùng mộtGPUvà triển khai chính sáchleast recently used evictionđể tối đa hóa hiệu suất. - Một giải pháp
inferenceđầy đủ choproductioncần tích hợprouting,auto-scaling,queuing mechanisms,monitoring(vớiPrometheus metricsvàGrafana), vàGPU provisioningtự động. - Hỗ trợ
mô hìnhđa dạng, đặc biệt là cácmô hình mã nguồn mở, đòi hỏi phảire-implementhoặc điều chỉnhforward passđể xử lý các kiến trúc khác nhau (ví dụ:flash attention,positional embeddings). - Tối ưu hóa
inferencecần tính đếnvariable length attentionvà cơ chếpaddingthông minh để tránh lãng phícomputetrên cácmã thông báotrống khi thực hiệntoken-based batching. Siecung cấp một nền tảngmã nguồn mởend-to-endbao gồm cảmodel inferenceđược điều chỉnh (nhưforward passtùy chỉnh) vàclusterquản lý, có sẵn dưới dạngHelm chartsvàDocker imagesđể triển khai dễ dàng.
Inference— Suy luận/Chạy suy luận mô hìnhContext Rot— Suy giảm ngữ cảnhOpen-source— Mã nguồn mởInfrastructure— Cơ sở hạ tầngModel— Mô hìnhFlash 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
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 ML và AI ứ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, routing và automation 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 search và document 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à:
- 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
inferencechoAI searchvàdocument processingthực sự quan trọng khi bạn đang xây dựng cáctác nhânhoặc khi bạn đang xây dựng cácworkflowliên quan đếntác nhân. Vì vậy, lý do tại sao điều này rất quan trọng. Inferencekhông phải là gì? Sau đó, tôi muốn nói với bạn về điều thứ hai, đó làinferencekhô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ủainference, nhưng không phải tất cả đều là về những điều đó.- 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ậninference, tôi gọi đây là "âm và dương củamodel inference", và đó là một cách kết hợp một vài điều xung quanhmodel supportvàinfrastructure.
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 code và grepping?" 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ó preprocess và filter 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ủ và 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 metrics và Grafana, 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 mechanisms và provisioning 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 BERT và Qwen 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, Qwen và BERT 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, key và value. 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 encoders và re-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 BERT và Qwen. Vì vậy, điều đó cần được tính đến. Trong ColBERT, nó cũng hoàn toàn khác. Query, key và value 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, score và extract. 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 charts và Docker 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.
TL;DR
Inferencecho cácmô hìnhAI nhỏ thường bị bỏ qua nhưng lại rất quan trọng để giải quyết vấn đềcontext rottrongAI searchvàdocument processing.- Các giải pháp
inferencetruyền thống không hiệu quả vớimô hìnhnhỏ; cần tối ưu hóa việc sử dụngGPUthông quahot-swappingvà hỗ trợ toàn diệncơ sở hạ tầngđể triển khaiproduction. Superlinked inference engine(Sie) là một giải phápmã nguồn mở,end-to-endgiúp giải quyết những thách thức này bằng cách hỗ trợ đa dạngmô hìnhvà cung cấpcluster supportmạnh mẽ.
Điểm chính
- Hiểu và tối ưu hóa
inferencecho cácmô hìnhnhỏ là rất quan trọng để quản lýngữ cảnhvà chống lạicontext rottrong cácworkflowcủatác nhân. - Các
mô hìnhnhỏ có thể được sử dụng hiệu quả chopreprocessingdữ liệu,tool callingvàcontext management, giúp giảm lượngmã thông báocần thiết cho cáctác nhânlớn. - Việc chỉ định một
GPUriêng cho mỗimô hìnhnhỏ là lãng phí tài nguyên; cần có khả nănghot-swapcácmô hìnhtrên cùng mộtGPUvà triển khai chính sáchleast recently used evictionđể tối đa hóa hiệu suất. - Một giải pháp
inferenceđầy đủ choproductioncần tích hợprouting,auto-scaling,queuing mechanisms,monitoring(vớiPrometheus metricsvàGrafana), vàGPU provisioningtự động. - Hỗ trợ
mô hìnhđa dạng, đặc biệt là cácmô hình mã nguồn mở, đòi hỏi phảire-implementhoặc điều chỉnhforward passđể xử lý các kiến trúc khác nhau (ví dụ:flash attention,positional embeddings). - Tối ưu hóa
inferencecần tính đếnvariable length attentionvà cơ chếpaddingthông minh để tránh lãng phícomputetrên cácmã thông báotrống khi thực hiệntoken-based batching. Siecung cấp một nền tảngmã nguồn mởend-to-endbao gồm cảmodel inferenceđược điều chỉnh (nhưforward passtùy chỉnh) vàclusterquản lý, có sẵn dưới dạngHelm chartsvàDocker imagesđể triển khai dễ dàng.
Từ vựng
Inference— Suy luận/Chạy suy luận mô hìnhContext Rot— Suy giảm ngữ cảnhOpen-source— Mã nguồn mởInfrastructure— Cơ sở hạ tầngModel— Mô hìnhFlash 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 ML và AI ứ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, routing và automation 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 search và document 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à:
- 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
inferencechoAI searchvàdocument processingthực sự quan trọng khi bạn đang xây dựng cáctác nhânhoặc khi bạn đang xây dựng cácworkflowliên quan đếntác nhân. Vì vậy, lý do tại sao điều này rất quan trọng. Inferencekhông phải là gì? Sau đó, tôi muốn nói với bạn về điều thứ hai, đó làinferencekhô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ủainference, nhưng không phải tất cả đều là về những điều đó.- 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ậninference, tôi gọi đây là "âm và dương củamodel inference", và đó là một cách kết hợp một vài điều xung quanhmodel supportvàinfrastructure.
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 code và grepping?" 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ó preprocess và filter 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ủ và 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 metrics và Grafana, 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 mechanisms và provisioning 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 BERT và Qwen 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, Qwen và BERT 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, key và value. 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 encoders và re-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 BERT và Qwen. Vì vậy, điều đó cần được tính đến. Trong ColBERT, nó cũng hoàn toàn khác. Query, key và value 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, score và extract. 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 charts và Docker 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.