# wxch: ระบบแบ่งปันทรัพยากร AI — ภาพรวมและแนวทางออกแบบ เอกสารนี้อธิบายว่าระบบ **ทำงานอย่างไร**, **แต่ละส่วนต้องทำอะไร**, และ **ถ้าฟอร์แมตเครื่องแล้วลงใหม่จะกลับมาได้อย่างไร** สถานะ: ร่างออกแบบ (ส่วนที่ทำแล้วระบุชัดในหัวข้อ 9) เรื่องเหรียญ/การซื้อขายสิทธิ์ **แยกเป็นงานต่างหาก ไม่อยู่ในเอกสารนี้** ## 1. หลักการ 1. **ใช้ได้จริงก่อน** นำเข้า/ลบ/แชร์โมเดล และเรียกใช้ผ่าน API ให้ได้ก่อนคิดเรื่องเหรียญ 2. **เจ้าของเครื่องมาก่อนเสมอ** เมื่อเจ้าของใช้เครื่อง ระบบต้องคืนทรัพยากรให้ ไม่ใช่ให้เจ้าของรอ 3. **หน่วยความจำไม่ค้างโดยไม่จำเป็น** โมเดลที่ไม่มีคนใช้ถูกปล่อย โมเดลที่ถูกใช้ต่อเนื่องค้างไว้ 4. **คะแนนวัดจากการให้บริการที่ดี** ไม่ใช่แค่ "เปิดเครื่องทิ้งไว้" 5. **เครื่องกลับมาได้ง่ายหลังฟอร์แมต** สถานะที่ต้องการ (desired state) อยู่ที่ server ไม่ใช่ที่เครื่อง 6. **โปร่งใสแต่ไม่ล้ำความเป็นส่วนตัว** ผู้เข้าร่วมเห็นสถานะทรัพยากรและสถิติ แต่ไม่เห็น prompt ของกันและกัน ## 2. ภาพรวมส่วนประกอบ ``` ผู้ใช้ / AIBIO / แอปที่รู้จัก OpenAI API │ HTTPS (API key) ▼ ┌─────────────────────── VPS: control.wxch.org / api.wxch.org ───────────────────────┐ │ Gateway (OpenAI-compatible) Scheduler (เลือกโหนด) Registry (โหนด/โมเดล) │ │ Metering (นับโทเค็น) Scoring (คะแนน) Desired state (ค่าที่ต้องการ)│ └───────────────▲──────────────────────────────▲──────────────────────────────────┘ │ wss (โหนดต่อออก ไม่ต้องเปิดพอร์ต)│ ┌────────┴─────────┐ ┌────────┴─────────┐ │ โหนด A (PGX) │ │ โหนด B ... │ │ wxch-agent │ │ wxch-agent │ │ ├ Model Pool │ └──────────────────┘ │ ├ Owner Guard │ │ ├ Telemetry │ │ └ Runtime (Ollama; vLLM/LM Studio ในอนาคต) └───────────────────┘ ``` | ส่วน | หน้าที่ | |---|---| | **Gateway** | รับคำขอแบบ OpenAI ตรวจ API key ส่งต่อให้โหนด นับโทเค็นจากฟิลด์ `usage` | | **Scheduler** | เลือกโหนดที่เหมาะที่สุดต่อคำขอ (หัวข้อ 4) | | **Registry** | จำว่าโหนดไหนออนไลน์ มีโมเดลอะไร พร้อมแค่ไหน | | **Desired state** | ค่าที่ต้องการของแต่ละโหนด: runtime, รายการโมเดล, เพดานทรัพยากร, ตารางเวลา | | **wxch-agent** | ต่อออกไปหา server ทำตามคำสั่ง รายงานสถานะ ควบคุม Model Pool และ Owner Guard | | **Model Pool** | โหลด/ปล่อยโมเดลตามกฎหัวข้อ 3 | | **Owner Guard** | ตรวจว่าเจ้าของกำลังใช้เครื่อง แล้วคืนทรัพยากร (หัวข้อ 5) | | **Telemetry** | ส่ง CPU/RAM/GPU/คิว/ความเร็วจริงทุก N วินาที | | **Scoring** | คิดคะแนนบริการ (หัวข้อ 7) | ## 3. วงจรชีวิตโมเดลบนแต่ละโหนด (Model Pool) สถานะ: `UNLOADED → LOADING → READY (ว่าง) ⇄ BUSY (มีงาน) → UNLOADED` กฎ: 1. **ค้างไว้ถ้ายังมีคนใช้ต่อเนื่อง** ทุกคำขอต่ออายุตัวจับเวลา idle (เช่น 5 นาที ตั้งค่าได้) หมดเวลาแล้วปล่อยหน่วยความจำ 2. **ขอโมเดลอื่นขณะหน่วยความจำไม่พอ** - ปล่อยโมเดลที่ `READY` และไม่มีงาน โดยเลือกตัวที่ถูกใช้ล่าสุดนานที่สุดก่อน (LRU) - **ห้ามตัดงานที่กำลังทำ** ถ้าโมเดลที่ครองหน่วยความจำยัง `BUSY` ให้รอจบ (มี timeout) หรือส่งคำขอไปโหนดอื่นที่เหมาะกว่า 3. **กันการโหลดสลับไปมา (thrash)** โมเดลที่เพิ่งโหลดต้องอยู่ขั้นต่ำช่วงหนึ่ง (เช่น 2 นาที) ก่อนถูกปล่อยเพราะคำขอของโมเดลอื่น การโหลดโมเดลใหญ่ใช้เวลาหลายนาที ต้องให้ Scheduler เลือกโหนดที่มีโมเดลนั้นพร้อมอยู่แล้วก่อน 4. **เช็กงบหน่วยความจำก่อนโหลด** ขนาดไฟล์โมเดล + KV cache ตาม context ที่ตั้ง + เผื่อระบบ (AIBIO ใช้หลักนี้อยู่แล้ว: เหลือว่างอย่างน้อยกี่ GiB ก่อนโหลด) ถ้าไม่พอให้ปฏิเสธโหลดและแจ้งเหตุผล ห้ามโหลดจนเครื่องค้าง 5. ต้องตั้ง `context length` ให้ runtime จริง ไม่ใช่แค่ในโปรไฟล์ (Ollama ใช้ค่าเริ่มต้นเล็กถ้าไม่ส่ง `num_ctx`) หมายเหตุ GB10: หน่วยความจำเป็น **unified** (CPU/GPU ใช้ร่วมกัน) และ `nvidia-smi` แสดง GPU memory เป็น "Not Supported" (เห็นจากผลจริงบน PGX) ดังนั้นต้องวัดหน่วยความจำจาก `/proc/meminfo` (`MemAvailable`) เป็นหลัก ไม่ใช่จาก NVML ## 4. Scheduler: เลือกโหนดให้แต่ละคำขอ ลำดับการตัดสินใจ: 1. คัดโหนดที่ **ออนไลน์, ไม่อยู่ในโหมดเจ้าของใช้งาน, มีโมเดลติดตั้ง** และสิทธิ์ผู้ใช้ตรงกับโมเดลนั้น 2. **ชอบโหนดที่โหลดโมเดลนั้นไว้แล้ว** (ไม่ต้องรอโหลด) 3. ในกลุ่มนั้น เลือกจาก **คิวสั้น, ความเร็วจริงสูง, คะแนนคุณภาพดี** 4. ถ้าไม่มีโหนดที่โหลดไว้ ให้เลือกโหนดที่ **โหลดได้โดยไม่ต้องตัดงาน** (หน่วยความจำพอหรือปล่อยตัวที่ว่างได้) 5. ถ้าไม่มี ให้เข้าคิวรอพร้อม timeout และตอบผู้ใช้ชัดเจน (เช่น 503 พร้อมเวลาโดยประมาณ) ไม่ปล่อยค้างเงียบ ## 5. เจ้าของเครื่องต้องใช้งานได้ (Owner Guard) โหมดโหนด: `AVAILABLE` (รับงาน) · `DRAINING` (ไม่รับงานใหม่ รอจบงานเดิม) · `OWNER` (เจ้าของใช้ ปล่อยทรัพยากรแล้ว) · `PAUSED` (เจ้าของหยุดแชร์เอง) ตัวบอกว่าเจ้าของกำลังใช้ (ใช้หลายตัวร่วมกัน เพราะตัวเดียวไม่แน่นอน): - มีการใช้คีย์บอร์ด/เมาส์หรือ session กราฟิก (เช่น `loginctl`/idle hint ของ desktop) - มีโปรเซสบน GPU/CPU ที่ **ไม่ใช่ของเรา** กินทรัพยากรเกินเกณฑ์ - `MemAvailable` ต่ำกว่าเกณฑ์ที่เจ้าของตั้ง - **ปุ่มสลับเอง** "ฉันกำลังใช้" (หน้าเว็บ/คำสั่ง `wxch-agent pause`) ต้องมีเสมอเพราะการตรวจอัตโนมัติพลาดได้ พฤติกรรม: 1. เจอสัญญาณเจ้าของ → เข้า `DRAINING` หยุดรับงานใหม่ ให้งานเดิมจบภายใน grace period (เช่น 30 วินาที) → ปล่อยโมเดลทั้งหมด → `OWNER` 2. เจ้าของว่างต่อเนื่องเกิน N นาที → กลับ `AVAILABLE` และโหลดโมเดลเมื่อมีคำขอ 3. **เพดานทรัพยากร** เจ้าของกำหนดได้: ใช้หน่วยความจำให้บริการได้ไม่เกินกี่ % / ช่วงเวลาที่ให้บริการ / ปิดช่วงที่ต้องการใช้เอง บังคับด้วย cgroup/systemd (`MemoryMax`) กันไม่ให้เกิน 4. เวลาที่อยู่ใน `OWNER`/`PAUSED` **ไม่ถูกหักคะแนน** (หัวข้อ 7) ไม่งั้นไม่มีใครกล้าแบ่งปัน ## 6. ผู้ร่วมระบบเห็นอะไร (Telemetry) ทุกโหนดส่งทุก ~5-10 วินาที: CPU%, RAM ว่าง, GPU util/อุณหภูมิ (ถ้ามี), โหมดโหนด, โมเดลที่โหลดอยู่/ติดตั้ง, ความยาวคิว, ความเร็วจริง (โทเค็น/วินาที, เวลาถึงโทเค็นแรก) ต่อโมเดล หน้า Dashboard (สำหรับผู้เข้าร่วม): แสดง **สรุป** ว่าเครื่องไหนพร้อมใช้เท่าไร ถูกใช้มากน้อย โมเดลอะไรมีให้บริการ **ไม่แสดง prompt/คำตอบ** ของใคร และแสดงเฉพาะข้อมูลที่เจ้าของเครื่องอนุญาต ## 7. คะแนนบริการ (ไม่ใช่เงิน) เป็นร่างเพื่อเริ่มทดลอง ปรับได้จากข้อมูลจริง: ``` คะแนน = (ปริมาณบริการ × ตัวคูณคุณภาพ) + โบนัสความพร้อม + โบนัสต่อเนื่อง ``` | องค์ประกอบ | วัดอย่างไร | น้ำหนัก | |---|---|---| | **ปริมาณบริการ** | โทเค็นที่ให้บริการจริง ถ่วงตามขนาด/ชั้นของโมเดล | มากที่สุด | | **คุณภาพ (ตัวคูณ)** | ความเร็วเทียบกับ **โหนดอื่นที่รันโมเดลเดียวกันบนฮาร์ดแวร์ระดับเดียวกัน** (โมเดลเดียวกันแต่ช้ากว่าชาวบ้าน = ตัวคูณต่ำ), อัตราข้อผิดพลาด, ผ่านคำถามตรวจสอบที่รู้คำตอบ, น้ำหนักโมเดลตรงกับที่ประกาศ | ปรับคะแนนบริการขึ้น/ลง | | **ความพร้อม** | สัดส่วนเวลาที่ `AVAILABLE` และตอบได้ เทียบกับเวลาที่ประกาศว่าให้บริการ (ไม่นับช่วง `OWNER`/`PAUSED`) | เป็นโบนัส มีเพดาน | | **ต่อเนื่อง** | ระยะเวลาออนไลน์ต่อเนื่องโดยไม่หลุดโดยไม่ตั้งใจ (log scale ผลตอบแทนลดลง) การหยุดชั่วคราวที่ตั้งใจไม่ตัดสถิติ | โบนัสเล็ก มีเพดาน | กันโกง: โบนัสทั้งหมดต้องไม่เกิน X% ของคะแนนบริการ (ป้องกันแค่เปิดเครื่องทิ้งไว้), สุ่มตรวจด้วยคำถามที่รู้คำตอบและส่งซ้ำไปหลายโหนดเป็นครั้งคราว, ตัดคำขอที่เจ้าของโหนดส่งหาตัวเอง, จำกัดบัญชีปลอมหลายบัญชี ## 8. ตั้งค่าเครื่องใหม่ / ฟอร์แมตแล้วลงใหม่ให้ขึ้นได้ง่าย แนวคิด: **เครื่องไม่เก็บ "ความจริง" ของตัวเอง** ตัวตน ค่าที่ต้องการ และคะแนนอยู่ที่ server เครื่องแค่ทำตามให้ตรง (reconcile) ขั้นตอนเป้าหมาย: 1. ลง DGX OS ด้วย USB กู้คืนทางการ (ที่เครื่อง) 2. พิมพ์คำสั่งเดียว พร้อม **รหัสลงทะเบียนสั้นๆ ใช้ครั้งเดียว** ที่ออกจากหน้าเว็บ `curl -fsSL https://control.wxch.org/install.sh | sudo sh -s -- <รหัส>` 3. agent ลงทะเบียนกับชื่อโหนดเดิม server ออก token ใหม่ (ตัวเก่าใช้ไม่ได้) คะแนนและประวัติของโหนดยังอยู่ 4. server ส่ง **desired state**: ติดตั้ง runtime, mount SSD เก็บโมเดล (ตาม UUID, `nofail`), ดึงโมเดลที่ขาดตามรายการ, ตั้งเพดานและตารางเวลา 5. โหนดกลับเป็น `AVAILABLE` เอง ผู้ดูแลทำที่เครื่องแค่ข้อ 1-2 หลักที่ทำให้ง่าย: - โมเดลอยู่ใน SSD แยก (ไม่หายตอนลง OS ใหม่) และมีรายการโมเดลที่ server เป็นกุญแจให้ดึงใหม่ - สคริปต์ setup แบ่งชั้นและรันซ้ำได้ (`00-base`, `10-docker`, `20-nvidia`, `30-runtime`) และทุกการเปลี่ยนแปลงผ่านสคริปต์ ไม่ทำมือแล้วลืม - ล็อกเวอร์ชัน driver/kernel และ Docker image ที่เสี่ยงเปลี่ยน - ซ้อมกู้ระบบจริงหนึ่งครั้งหลังทำเสร็จ วัดเวลา ขั้นตอนที่ใช้ได้ **วันนี้** (ก่อนมีรหัสลงทะเบียนสั้น): ที่ server รัน `sudo -u wxch /opt/wxch/wxch-server -config /opt/wxch/config.json -add-agent <ชื่อ>` (ถ้าชื่อมีแล้ว ให้ลบรายการเดิมใน `config.json` ก่อน) จะได้คำสั่งติดตั้งพร้อม token นำไปพิมพ์ที่เครื่อง ## 9. สถานะปัจจุบัน | รายการ | สถานะ | |---|---| | server/agent/เว็บ, terminal จากระยะไกล, Run script | ทำแล้ว ใช้งานได้ (ทดสอบกับ PGX จริง) | | ล็อกอินรหัสผ่าน (2FA เป็นตัวเลือก ปิดไว้เป็นค่าเริ่มต้น), เปลี่ยนรหัสผ่าน, สลับภาษา/ธีม | ทำแล้ว | | notepad.wxch.org (คลิปบอร์ดกลาง ส่ง/อ่าน/ลบ) | ทำแล้ว | | ติดตั้ง agent ด้วยคำสั่งเดียว และเพิ่มหลายเครื่อง (`-add-agent`) | ทำแล้ว (ยังไม่มีรหัสลงทะเบียนสั้น) | | รหัสลงทะเบียนสั้น + ลงทะเบียนซ้ำชื่อเดิม | ยังไม่ทำ | | ช่องคำสั่งแบบมีโครงสร้าง (list/pull/delete โมเดล) + หน้า Models | ยังไม่ทำ (ขั้นถัดไป) | | Gateway แบบ OpenAI + API key + วัดโทเค็น (หน้า API) | ทำแล้ว ทดสอบบน PGX จริง (ดู API-TH.md) — รอเพิ่ม DNS `api` | | Telemetry + Dashboard | ทำแล้ว | | Model Pool + Scheduler (เลือกเครื่อง) | ทำแล้ว (ปล่อยโมเดลสลับยังทดสอบด้วยเทสต์จำลองเท่านั้น) | | Owner Guard (หยุดรับงาน → รอจบ/ยกเลิก → ปล่อยโมเดล; ปุ่มหยุดแชร์; `wxch-agent -pause`) | ทำแล้ว ทดสอบการหยุดแชร์บน PGX จริง; การตรวจเมาส์/คีย์บอร์ดและโปรเซส GPU อื่น ผ่านเทสต์จำลองแต่ยังไม่ได้ทดสอบกับคนจริงบนเครื่อง | | แคตตาล็อกโมเดลพื้นฐาน (ดาวน์โหลดคลิกเดียว) | ทำแล้ว (เฉพาะรุ่นที่ใช้ Ollama; vLLM/LM Studio รอ runtime) | | Scoring, โควตา, วัดการใช้งาน | ยังไม่ทำ | | เหรียญ/ซื้อขายสิทธิ์ | แยกเป็นงานต่างหาก | ## 10. ลำดับงานที่แนะนำ 1. **จัดการโมเดล** — ช่องคำสั่งมีโครงสร้าง + หน้า Models (นำเข้า/ลบ/ดูพื้นที่) ด้วย Ollama เป็นตัวแรก เก็บโมเดลบน SSD แยก 2. **Telemetry + Dashboard** — เห็นสถานะเครื่องจริงก่อนตัดสินใจเรื่องอื่น (ทำก่อน Owner Guard เพราะต้องรู้ว่าวัดอะไรได้บน GB10) 3. **Gateway + Model Pool + Scheduler (โหนดเดียว)** — API แบบ OpenAI โหลดตามต้องการ ปล่อยเมื่อว่าง สลับโมเดลตามกฎ 4. **Owner Guard** — ตรวจการใช้งานเจ้าของ คืนทรัพยากร ปุ่มหยุดแชร์ 5. **รหัสลงทะเบียน + desired state + reconcile** — ฟอร์แมตแล้วกลับมาเองได้ 6. **หลายโหนด + หลายผู้ใช้ + คะแนน** — ทดลองกับเครื่องที่ไว้ใจก่อน ## 11. ความเสี่ยงและข้อที่ต้องตัดสินใจ - **ความเป็นส่วนตัว:** เจ้าของโหนดเห็น prompt ที่ผ่านเครื่องตัวเองได้ ฮาร์ดแวร์ทั่วไปซ่อนไม่ได้ จึงต้องแจ้งผู้ใช้ชัดเจน และแยกโหนดที่ไว้ใจได้ออกจากโหนดสาธารณะ - **ใบอนุญาตโมเดล:** บางรุ่นจำกัดการแจกจ่ายต่อ ให้ **ให้ใช้ผ่าน API** ปลอดภัยกว่า **แจกไฟล์โมเดล** และบันทึก license ของแต่ละรุ่น - **ความปลอดภัยของไฟล์โมเดล:** รับเฉพาะ GGUF/safetensors ไม่รับรูปแบบ pickle จากแหล่งไม่น่าเชื่อถือ - **การตรวจว่าเจ้าของใช้งาน** อาจพลาด จึงต้องมีปุ่มสลับเองเสมอ - **ความเป็นธรรมของคะแนน** ต่างฮาร์ดแวร์ต่างความเร็ว ต้องเทียบในกลุ่มที่เทียบกันได้ และปรับน้ำหนักจากข้อมูลจริง - **ความรับผิดชอบต่อเนื้อหา** ต้องมีข้อกำหนดการใช้งานก่อนเปิดให้คนนอก - **แบนด์วิดท์/ดิสก์ของ VPS** จำกัด อย่าให้ไฟล์โมเดลวิ่งผ่าน VPS ให้โหนดดาวน์โหลดตรงจากต้นทาง ## 12. ข้อมูลลับ อย่าบันทึก token, รหัสผ่าน หรือ TOTP secret ลงในเอกสารหรือโค้ด เก็บใน `/opt/wxch/config.json` บน server (สิทธิ์ 0600) และ `/etc/wxch-agent.env` บนโหนด