สถาปัตยกรรมใหม่สำหรับแอปพลิเคชัน LLM
(a16z.com)- "Reference architecture สำหรับสแตกของแอป LLM" ที่ a16z สรุปไว้
Emerging LLM App Stack
Contextual Data
- Data Pipelines: Databricks, Airflow, Unstructured,..
- Embedding Model: OpenAI, Cohere, Hugging Face
- Vector Database: Pinecone, Weaviate, Chroma, pgvector
Prompt Few-shot Examples
- Playground: OpenAI, nat.dev, Humanloop
- Orchestration: Pytion/DIY, LangChain, LlamaIndex, ChatGPT
- APIs/Plugins: Serp, Wolfram, Zapier,...
Query & Output
- App Hosting: Vercel, Steamship, Streamlit, Modal
- LLM Cache: Redis, SQLite, GPTCache
- Logging/LLMops: Weights & Biases, MLflow, PromptLayer, Helicone
- Validation: Guardrails, Rebuff, Guidance, LMQL
LLM APIs and Hosting
- Proprietary API: OpenAI, Anthropic
- Open API: Hugging Face, Replicate
- Cloud Provider: AWS, GCP, Azure, Coreweave
- Opinionated Cloud: Databricks, Anyscale, Mosaic, Modal, Runpod,...
Design Pattern: In-context Learning
- In-Context Learning: การใช้งาน LLM แบบเดิมโดยไม่ต้อง fine-tuning แต่ใช้การเขียนพรอมป์อย่างชาญฉลาดและเงื่อนไขที่อิงกับข้อมูลแบบ "Contextual" บางส่วน
- ตัวอย่าง) หากต้องการสร้างแชตบอตที่ตอบคำถามเกี่ยวกับเอกสารกฎหมาย ถ้าทำแบบ naive ก็อาจแค่ใส่เอกสารทั้งหมดเข้าไปใน ChatGPT แล้วถามได้เลย แต่ทำได้แค่กับชุดข้อมูลขนาดเล็กเท่านั้น แม้แต่โมเดลที่ใหญ่ที่สุดของ ChatGPT ก็รองรับได้เพียงราว 50 หน้า
ใน In-Context Learning จะส่งเฉพาะเอกสารที่เกี่ยวข้องเข้าไป แล้วให้ตอบจากเอกสารเหล่านั้น - ดังนั้นจึงประกอบด้วยเวิร์กโฟลว์ 3 ขั้นตอนดังนี้
- Step 1. การเตรียมข้อมูลล่วงหน้า / embedding
- Step 2. การสร้างพรอมป์ / retrieval เอกสารที่เกี่ยวข้องจาก Vector DB
- Step 3. การรันพรอมป์ / inference
- แม้จะดูเหมือนมีงานหลายส่วน แต่ก็ง่ายกว่าการฝึกและ fine-tuning ตัว LLM เองมาก
Step 1. [Data preprocessing / embedding]
→ Contextual Data ผ่าน Data Pipeline แล้วผ่าน Embedding Model ก่อนจะถูกจัดเก็บใน Vector Database
Contextual Data
- เอกสารข้อความ, PDF, CSV และตาราง SQL
- โดยส่วนใหญ่ยังคงใช้เครื่องมือ ETL เดิม (Databricks, Airflow) สำหรับการโหลดและแปลงข้อมูล
- บางส่วนใช้ document loader ที่ฝังมาใน orchestration framework อย่าง LangChain และ LlamaIndex
- ผู้เขียนมองว่าส่วนนี้ของสแตกยังพัฒนาไม่มากนักเมื่อเทียบกับส่วนอื่น และยังมีโอกาสสำหรับโซลูชัน data replication ที่สร้างมาเพื่อแอป LLM โดยเฉพาะ
Embeddings
- นักพัฒนาส่วนใหญ่ใช้ OpenAI API (
text-embedding-ada-002)- ใช้งานง่าย ให้ผลลัพธ์ที่ดีในระดับเหมาะสม และมีราคาถูกลงเรื่อย ๆ
- บริษัทขนาดใหญ่บางแห่งกำลังสำรวจ Cohere ซึ่งให้ประสิทธิภาพที่ดีกว่าในบางกรณี
- นักพัฒนาที่ชอบโอเพนซอร์สมักใช้ไลบรารี Sentence Transformers ของ Hugging Face เป็นมาตรฐาน
- นอกจากนี้ยังสามารถ สร้าง embedding ได้หลายประเภท ให้เหมาะกับ use case
- แม้จะเป็นกรณีเฉพาะทาง แต่ก็เป็นหัวข้องานวิจัยที่มีอนาคต
Vector Database
- ส่วนที่สำคัญที่สุดในพายป์ไลน์การเตรียมข้อมูลล่วงหน้าคือ vector database
- ทำหน้าที่จัดเก็บ เปรียบเทียบ และค้นหา embedding (เวกเตอร์) จำนวนมากได้อย่างมีประสิทธิภาพ สูงสุดระดับหลายพันล้านรายการ
- ตัวเลือกที่พบได้บ่อยที่สุดในตลาดคือ Pinecone
- โฮสต์บนคลาวด์เต็มรูปแบบ ทำให้เริ่มใช้งานได้ง่าย
- มีฟีเจอร์จำนวนมากที่องค์กรขนาดใหญ่ต้องการในโปรดักชัน เช่น ประสิทธิภาพที่ดี, SSO, uptime SLA เป็นต้น
- อย่างไรก็ตาม vector database ที่ใช้งานได้มีอยู่มากมาย โดยเฉพาะ:
- โอเพนซอร์สอย่าง Weaviate, Vespa, Qdrant
- ให้ประสิทธิภาพแบบ single-node ที่ยอดเยี่ยม และปรับแต่งให้เหมาะกับแอปเฉพาะได้
- ได้รับความนิยมในทีม AI ที่มีประสบการณ์และชอบสร้างแพลตฟอร์มแบบปรับแต่งเอง
- ไลบรารีจัดการเวกเตอร์แบบ local อย่าง Chroma, Faiss
- มอบประสบการณ์นักพัฒนาที่ยอดเยี่ยม
- ใช้งานได้ง่ายสำหรับแอปขนาดเล็กและการทดลองพัฒนา
- ไม่ได้มีไว้แทนฐานข้อมูลขนาดใหญ่แบบเต็มรูปแบบ
- ส่วนขยาย OLTP อย่าง pgvector
- เป็นโซลูชันที่ดีสำหรับการรองรับเวกเตอร์สำหรับนักพัฒนาที่อยากยัดทุกความต้องการด้านฐานข้อมูลไว้ใน Postgres หรือองค์กรที่ซื้อโครงสร้างพื้นฐานข้อมูลส่วนใหญ่จากผู้ให้บริการคลาวด์รายเดียว
- ในระยะยาวยังไม่ชัดเจนว่าการผูกเวิร์กโหลด vector และ scalar เข้าด้วยกันแน่น ๆ นั้นเหมาะสมหรือไม่
- โอเพนซอร์สอย่าง Weaviate, Vespa, Qdrant
- หากมองไปข้างหน้า บริษัท vector database โอเพนซอร์สส่วนใหญ่กำลังพัฒนาผลิตภัณฑ์คลาวด์
- จากงานวิจัยของเรา การทำให้ได้ประสิทธิภาพที่ยอดเยี่ยมบนคลาวด์สำหรับ use case ที่หลากหลายนั้นยากมาก
- ดังนั้นตัวเลือกเหล่านี้อาจยังไม่เปลี่ยนในระยะสั้น แต่มีแนวโน้มจะเปลี่ยนในระยะยาว
- คำถามสำคัญคือ vector database จะรวมศูนย์ไปเป็นระบบชื่อดังเพียงหนึ่งหรือสองระบบเหมือนกรณี OLTP และ OLAP หรือไม่
- อีกคำถามหนึ่งคือ เมื่อ context window ที่ใช้ได้ในโมเดลส่วนใหญ่มีขนาดใหญ่ขึ้น embedding และ vector database จะพัฒนาไปอย่างไร
- อาจน่าดึงดูดที่จะบอกว่าเมื่อสามารถใส่ contextual data ทั้งหมดลงในพรอมป์ได้แล้ว embedding ก็จะไม่จำเป็น
- แต่ฟีดแบ็กจากผู้เชี่ยวชาญต่อเรื่องนี้คือ embedding pipeline อาจยิ่งสำคัญขึ้นเรื่อย ๆ
- context window ขนาดใหญ่เป็นเครื่องมือที่ทรงพลัง แต่ก็มาพร้อมต้นทุนการคำนวณที่สูงมาก ดังนั้นสิ่งสำคัญคือการใช้งานมันอย่างมีประสิทธิภาพ
- ต่อจากนี้เราน่าจะได้เห็น embedding model หลายประเภทกลายเป็นกระแสหลัก ได้รับการฝึกโดยตรงด้วยความเกี่ยวข้องของโมเดล และมี vector database ที่ช่วยเปิดใช้งานและใช้ประโยชน์จากสิ่งเหล่านี้ได้อย่างมีประสิทธิภาพ
Step 2. [Prompt construction / retrieval]
- กลยุทธ์ในการผสาน LLM prompting เข้ากับข้อมูลที่เหมาะกับบริบทกำลังซับซ้อนขึ้นเรื่อย ๆ และมีความสำคัญมากขึ้นเรื่อย ๆ ในฐานะแหล่งของความแตกต่างของผลิตภัณฑ์
- นักพัฒนาส่วนใหญ่มักเริ่มโปรเจ็กต์ใหม่ด้วยพรอมป์ง่าย ๆ ที่ประกอบด้วยคำสั่งตรง ๆ (zero-shot prompting) หรือมีตัวอย่างไม่กี่รายการ (few-shot prompting)
- พรอมป์เหล่านี้อาจให้ผลลัพธ์ที่ดีได้ แต่ยังไม่ถึงระดับความแม่นยำที่จำเป็นสำหรับการนำขึ้นโปรดักชัน
- ขั้นต่อไปของ prompting คือการออกแบบให้คำตอบของโมเดลมีหลักอ้างอิงจากแหล่งข้อมูลจริงบางส่วน และให้บริบทภายนอกที่โมเดลไม่ได้ถูกฝึกมาก่อน
- Prompt Engineering Guide ได้สรุปกลยุทธ์พรอมป์ขั้นสูงไว้ 12 แบบ
- ตรงนี้เองที่ orchestration framework อย่าง LangChain/LlamaIndex โดดเด่นขึ้นมา
- พวกมันช่วย abstract รายละเอียดจำนวนมากของ prompt chaining
- เช่น การเชื่อมต่อ external API, การดึง contextual data จาก vector database, การเก็บ memory ระหว่างการเรียก LLM หลายรอบ
- และยังมีเทมเพลตสำหรับโปรแกรมทั่วไปจำนวนมาก
- ผลลัพธ์ของมันคือพรอมป์หรือหลายพรอมป์ที่จะส่งไปยัง language model
- ในหมู่สตาร์ตอัปและนักพัฒนางานอดิเรก LangChain ถูกใช้มากที่สุด
- LangChain ยังเป็นโปรเจ็กต์ใหม่อยู่ (เวอร์ชันปัจจุบัน 0.0.220)
- แต่เริ่มเห็นแอปที่ใช้มันถูกนำขึ้นโปรดักชันแล้ว
- นักพัฒนาบางราย โดยเฉพาะกลุ่ม early adopter ของ LLM ชอบเปลี่ยนไปใช้ Python ล้วนในโปรดักชันเพื่อลด dependency
- แต่เรามองว่าแนวทาง DIY นี้จะค่อย ๆ ลดลงเหมือนที่เกิดในเว็บแอปสแตก (ส่วนใหญ่จะหันมาใช้เฟรมเวิร์ก)
- ผู้อ่านที่สังเกตเก่งอาจเห็นว่าในกล่อง orchestration มี ChatGPT อยู่ด้วย
- โดยทั่วไป ChatGPT เป็นแอป ไม่ใช่เครื่องมือสำหรับนักพัฒนา แต่สามารถเข้าถึงได้ผ่าน API
- ในอีกมุมหนึ่ง มันทำงานคล้าย orchestration framework เหล่านี้ได้ (abstract พรอมป์, เก็บสถานะ, ค้นหา contextual data ผ่านปลั๊กอิน เป็นต้น)
- แม้จะไม่ใช่คู่แข่งโดยตรงของเครื่องมือที่พูดถึงที่นี่ แต่ ChatGPT ก็อาจถือเป็นโซลูชันทดแทนได้ เป็นทางเลือกที่เรียบง่ายสำหรับการตั้งค่าและใช้งานอย่างรวดเร็ว
Step 3. [Prompt execution / inference]
- ปัจจุบัน OpenAI เป็นผู้นำในบรรดา language model
- นักพัฒนาแทบทั้งหมดเริ่มสร้างแอป LLM ด้วยโมเดล GPT-4 และ GPT-4-32k
- ใช้งานง่าย ใช้ได้ในหลายโดเมน และไม่ต้อง fine-tuning หรือ self-hosting
- เมื่อเข้าสู่โปรดักชันและขยายสเกล ก็จะมีตัวเลือกที่หลากหลายมากขึ้น
- เปลี่ยนไปใช้
gpt-3.5-turbo:- ถูกกว่ามากกว่า 50 เท่า และเร็วกว่ามากเมื่อเทียบกับ GPT-4
- เหมาะเมื่อไม่ต้องการความแม่นยำระดับ GPT-4 แต่ต้องการเวลาตอบสนองเร็ว หรือจำเป็นต้องรองรับผู้ใช้ฟรีอย่างมีประสิทธิภาพ
- ทดลองโมเดลจากผู้ขายรายอื่น (โดยเฉพาะ Claude ของ Anthropic)
- Claude ให้ inference ที่รวดเร็ว ความแม่นยำระดับ GPT-3.5 มีตัวเลือกปรับแต่งมากกว่า และรองรับ context window สูงสุด 100k (แต่เมื่อยาวมาก ความแม่นยำจะลดลง)
- แยกบางคำขอไปยังโมเดลโอเพนซอร์ส
- อาจมีประสิทธิภาพสำหรับ use case แบบ B2C ขนาดใหญ่ เช่น search/chat ที่มีความซับซ้อนของคิวรีหลากหลาย หรือจำเป็นต้องให้บริการผู้ใช้ฟรีในต้นทุนต่ำ
- เปลี่ยนไปใช้
- ปัจจุบันโมเดลโอเพนซอร์สยังคงไล่ตามผลิตภัณฑ์แบบ proprietary แต่ช่องว่างเริ่มแคบลง
- โมเดล LLaMA ของ Meta ได้ตั้งมาตรฐานใหม่ด้านความแม่นยำของโอเพนซอร์ส และทำให้เกิดรุ่นดัดแปลงมากมาย
- แม้ LLaMA จะอนุญาตเพื่อการวิจัยเท่านั้น แต่ผู้ให้บริการหลายรายก็เข้ามามีส่วนร่วมเพื่อฝึก base model ทางเลือก (Together, Mosaic, Falcon, Mistral)
- มีการพูดคุยว่า Meta จะเปิดตัวโมเดล LLaMa 2 แบบโอเพนซอร์สอย่างแท้จริง
- หาก LLM โอเพนซอร์สไปถึงระดับความแม่นยำใกล้เคียง GPT-3.5 เราน่าจะได้เห็นช่วงเวลาแบบ Stable Diffusion Moment ในโลกของข้อความ
- เช่น การทดลองขนาดใหญ่ การแชร์ และการนำโมเดลที่ fine-tune แล้วขึ้นโปรดักชัน
- บริษัทโฮสติ้งอย่าง Replicate ก็กำลังเพิ่มเครื่องมือเพื่อให้นักพัฒนาใช้โมเดลเหล่านี้ได้ง่ายขึ้น
- นักพัฒนาเริ่มเชื่อมากขึ้นว่าโมเดลที่เล็กกว่าแต่ fine-tune แล้วสามารถไปถึงความแม่นยำของโมเดลล้ำสมัยได้
- นักพัฒนาส่วนใหญ่ที่เราได้พูดคุยด้วยยังไม่ได้ลงลึกมากนักในเรื่องเครื่องมือปฏิบัติการสำหรับ LLM
- การทำ caching เป็นเรื่องทั่วไป โดยมักใช้ Redis (เพราะช่วยปรับปรุงเวลาตอบสนองและต้นทุน)
- เครื่องมืออย่าง Weights & Biases, MLFlow, PromptLayer, Helicone ก็ถูกใช้กันมาก
- สามารถ log, trace และ evaluate เอาต์พุตของ LLM เพื่อช่วยสร้างพรอมป์อย่างรวดเร็ว ปรับจูนพายป์ไลน์ และเลือกโมเดลได้
- เครื่องมือสำหรับตรวจสอบเอาต์พุตของ LLM (Guardrails) หรือการตรวจจับ prompt injection (Rebuff) ก็เริ่มมีมากขึ้น
- เครื่องมือปฏิบัติการเหล่านี้ส่วนใหญ่แนะนำให้ใช้ Python client ของตัวเองในการเรียก LLM ดังนั้นการได้เห็นว่าพวกมันจะอยู่ร่วมกันอย่างไรต่อไปก็น่าสนใจ
- สุดท้ายแล้ว ส่วนที่เป็น static ของ LLM (ทุกอย่างนอกเหนือจากตัวโมเดล) ก็ต้องถูกโฮสต์ไว้ที่ไหนสักแห่งเช่นกัน
- โซลูชันที่พบบ่อยที่สุดคือ Vercel หรือผู้ให้บริการคลาวด์รายใหญ่
- แต่กำลังมีหมวดหมู่ใหม่สองแบบเกิดขึ้น
- Steamship ให้บริการโฮสติ้งแบบ end-to-end สำหรับแอป LLM พร้อมความสามารถอย่าง orchestration (LangChain), multi-tenant data context, asynchronous task, vector store, key management เป็นต้น
- Anyscale และ Modal ช่วยให้นักพัฒนาสามารถโฮสต์ทั้งโมเดลและโค้ด Python ไปพร้อมกันได้
แล้ว Agent ล่ะ?
- องค์ประกอบสำคัญที่สุดที่ขาดหายไปจาก reference architecture นี้คือ AI Agent Framework
- AutoGPT เคยเป็น GitHub repo ที่เติบโตเร็วที่สุดในประวัติศาสตร์เมื่อฤดูใบไม้ผลิที่ผ่านมา โดยเป็น "การทดลองโอเพนซอร์สเพื่อทำให้ GPT-4 กลายเป็นระบบอัตโนมัติอย่างสมบูรณ์"
- ทุกโปรเจ็กต์ AI ทุกวันนี้ล้วนมี agent อยู่ในรูปแบบใดรูปแบบหนึ่ง
- นักพัฒนาส่วนใหญ่ที่เราได้คุยด้วยตื่นเต้นกับศักยภาพของ agent อย่างมาก
- รูปแบบ in-context learning ที่อธิบายในบทความนี้รองรับงานสร้างคอนเทนต์ได้ดีกว่า และช่วยแก้ปัญหา hallucination กับความสดใหม่ของข้อมูล
- ในขณะที่ agent มอบความสามารถใหม่อย่างพื้นฐานให้กับแอป AI
- เช่น การแก้ปัญหาที่ซับซ้อน การลงมือทำบางอย่างกับโลกภายนอก หรือการเรียนรู้จากประสบการณ์แม้หลัง deploy แล้ว
- โดยทำสิ่งเหล่านี้ผ่านการผสมผสานของการให้เหตุผล/การวางแผนขั้นสูง การใช้เครื่องมือ memory/recursion/self-reflection เป็นต้น
- agent มีโอกาสจะกลายเป็นส่วนศูนย์กลางของสถาปัตยกรรมแอป LLM (และถ้าเชื่อในเรื่องการพัฒนาตัวเองผ่าน recursion มันอาจครอบคลุมทั้งสแตกได้เลย)
- เฟรมเวิร์กอย่าง LangChain ก็ได้ผสานแนวคิด agent เข้าไปแล้ว
- มีปัญหาอยู่เพียงข้อเดียวคือ ตอนนี้ agent ยังทำงานได้ไม่ดีพอ
- ปัจจุบันเฟรมเวิร์ก agent ส่วนใหญ่อยู่ในขั้น PoC — ทำเดโมที่น่าทึ่งได้ แต่ยังไม่เสถียรหรือทำซ้ำผลได้สม่ำเสมอ
- เรากำลังจับตาดูว่ามันจะพัฒนาไปอย่างไร
มองไปข้างหน้า
- โมเดล AI ที่ผ่านการ pre-train แล้วคือการเปลี่ยนแปลงทางสถาปัตยกรรมที่สำคัญที่สุดของซอฟต์แวร์นับตั้งแต่อินเทอร์เน็ต
- สิ่งนี้ทำให้นักพัฒนาแต่ละคนสามารถสร้างแอป AI ภายในไม่กี่วัน ที่เหนือกว่าโปรเจ็กต์ supervised machine learning ซึ่งทีมขนาดใหญ่ต้องใช้เวลาหลายเดือนในการสร้าง
- เครื่องมือและแพตเทิร์นที่แนะนำไว้ที่นี่มีแนวโน้มจะเป็นเพียงจุดเริ่มต้นสำหรับการผสาน LLM มากกว่าจะเป็นสภาพสุดท้าย
6 ความคิดเห็น
เป็นบทความที่ให้ความรู้เชิงลึกและสัมผัสได้ถึงประสบการณ์จริงนะครับ
คิดว่าน่าจะช่วยได้มากในการออกแบบสถาปัตยกรรม LLM APP โดยอิงจากเนื้อหานี้
เนื่องจากใน ecosystem ยังไม่มีผู้ชนะที่ชัดเจนในแต่ละด้าน จึงอยู่ในสถานการณ์ที่มีโซลูชันหลากหลายปะปนกัน
ทำให้ปัญหาเรื่องการเลือกมีมากขึ้น และดูเหมือนว่าตอนนี้ความสามารถสำคัญคือการหาชุดผสมที่เหมาะสมให้ตรงกับความต้องการของตัวเอง
บทความนี้อัดแน่นมากเลยครับ กำลังค่อย ๆ อ่านอยู่ครับ
ถ้านำ GN ไปฝึกให้กับ LLM คุณกูรูก็จะสบายขึ้นไหมครับ? ^^;
ขอบคุณครับ
อ๊ะ คุณสร้าง GN+ ขึ้นมาแล้วสินะ :-o
น่าจะสะดวกขึ้นอยู่เหมือนกัน แต่บทความแบบนี้ก็คงจะอ่านต่อไปเรื่อย ๆ ในแง่ของการได้ศึกษาไปด้วย ฮ่าๆ
ถ้า GN⁺ จัดการข่าวอื่น ๆ ให้หมดได้ ก็อาจเกิดผลให้บทความแนวนี้เพิ่มขึ้นอีกก็ได้!
ขอบคุณสำหรับบทความและสรุปที่ดีครับ