# 🤖 LiteRT-LM Web Server Chạy mô hình **Gemma 4** trên thiết bị nhúng (Orange Pi 5, Raspberry Pi, v.v.) thông qua [LiteRT-LM](https://github.com/google-ai-edge/litert-lm) với giao diện REST API và Web UI. --- ## 📋 Yêu cầu - Python 3.10+ - [`litert-lm`](https://github.com/google-ai-edge/litert-lm) đã cài và hoạt động - Model file: `gemma-4-E2B-it.litertlm` (hoặc model `.litertlm` khác) - Thư viện Python: ```bash pip install fastapi uvicorn pydantic ``` --- ## 📁 Cấu trúc ``` . ├── app.py # REST API đơn giản, single-turn ├── server.py # REST API đầy đủ + Web UI, multi-turn sessions └── README.md ``` --- ## 🚀 Hướng dẫn sử dụng ### Bước 1 — Đặt model vào cùng thư mục ``` gemma-4-E2B-it.litertlm ← model file app.py server.py ``` Nếu model ở chỗ khác, sửa biến `MODEL_PATH` ở đầu mỗi file. --- ## 📄 `app.py` — REST API đơn giản File cơ bản, phù hợp để tích hợp nhanh hoặc test. ### Chạy ```bash python app.py ``` Server khởi động tại `http://0.0.0.0:8000` ### Endpoint #### `POST /generate` Gửi một prompt, nhận phản hồi. Mỗi request là độc lập, **không có bộ nhớ** giữa các lần gọi. ```bash curl -X POST http://localhost:8000/generate \ -H "Content-Type: application/json" \ -d '{"prompt": "Bạn là ai?"}' ``` **Response:** ```json { "response": "Tôi là Gemma 4, một Mô hình Ngôn ngữ Lớn...", "tokens": 42, "elapsed_s": 5.31, "tokens_per_sec": 7.91 } ``` --- ## 🖥️ `server.py` — REST API đầy đủ + Web UI Phiên bản đầy đủ với hỗ trợ multi-turn conversation, quản lý session và giao diện chat trên trình duyệt. ### Chạy ```bash python server.py ``` Server khởi động tại `http://0.0.0.0:8000` --- ### 🌐 Web UI Mở trình duyệt và truy cập: ``` http://<địa-chỉ-ip>:8000 ``` Tính năng: - Giao diện chat trực quan, hỗ trợ tiếng Việt - Tự động tạo session khi mở trang - Nhớ ngữ cảnh hội thoại trong cùng một session - Nút **New** để bắt đầu cuộc trò chuyện mới - Nút **Clear** để xóa lịch sử và tạo session mới - `Enter` để gửi, `Shift + Enter` để xuống dòng - **Render Markdown**: câu trả lời của model hiển thị đúng định dạng (heading, list, code block, table, bold/italic, v.v.) - **Đo tốc độ**: badge `⚡ X tok/s` hiển thị bên dưới mỗi câu trả lời, kèm tổng số token và thời gian xử lý --- ### 🔌 REST API #### `POST /generate` Single-turn, không nhớ context. Dùng khi chỉ cần hỏi đáp đơn lẻ. ```bash curl -X POST http://localhost:8000/generate \ -H "Content-Type: application/json" \ -d '{"prompt": "Thủ đô của Việt Nam là gì?"}' ``` --- #### `POST /chat/new` Tạo một session mới. Trả về `session_id` dùng cho các request tiếp theo. ```bash curl -X POST http://localhost:8000/chat/new ``` **Response:** ```json { "session_id": "a3f2c1d4-..." } ``` --- #### `POST /chat/{session_id}` Gửi tin nhắn trong một session. Model **nhớ toàn bộ lịch sử hội thoại** trong session đó. ```bash curl -X POST http://localhost:8000/chat/a3f2c1d4-... \ -H "Content-Type: application/json" \ -d '{"prompt": "Kể thêm về điều đó đi"}' ``` **Response:** ```json { "session_id": "a3f2c1d4-...", "response": "...", "tokens": 58, "elapsed_s": 7.12, "tokens_per_sec": 8.15 } ``` --- #### `DELETE /chat/{session_id}` Xóa session và giải phóng bộ nhớ. ```bash curl -X DELETE http://localhost:8000/chat/a3f2c1d4-... ``` **Response:** ```json { "status": "cleared", "session_id": "a3f2c1d4-..." } ``` --- #### `GET /chat/sessions/list` Liệt kê tất cả session đang hoạt động. ```bash curl http://localhost:8000/chat/sessions/list ``` **Response:** ```json { "sessions": ["a3f2c1d4-...", "b7e9f2a1-..."], "count": 2 } ``` --- ## 💡 Ví dụ: Multi-turn conversation qua curl ```bash # 1. Tạo session SESSION=$(curl -s -X POST http://localhost:8000/chat/new | python3 -c "import sys,json; print(json.load(sys.stdin)['session_id'])") # 2. Gửi tin nhắn đầu tiên curl -s -X POST http://localhost:8000/chat/$SESSION \ -H "Content-Type: application/json" \ -d '{"prompt": "Tên tôi là Nam"}' | python3 -m json.tool # 3. Model nhớ context curl -s -X POST http://localhost:8000/chat/$SESSION \ -H "Content-Type: application/json" \ -d '{"prompt": "Tên tôi là gì?"}' | python3 -m json.tool # 4. Xóa session khi xong curl -X DELETE http://localhost:8000/chat/$SESSION ``` --- ## ⚙️ Cấu hình Các tham số có thể chỉnh trong đầu mỗi file: | Biến | Mô tả | Mặc định | |------|-------|---------| | `MODEL_PATH` | Đường dẫn đến file model | `gemma-4-E2B-it.litertlm` | | `backend` | Backend inference | `litert_lm.Backend.CPU` | | `host` | Địa chỉ lắng nghe | `0.0.0.0` | | `port` | Cổng | `8000` | Để đổi backend sang GPU (nếu thiết bị hỗ trợ): ```python engine = litert_lm.Engine(MODEL_PATH, backend=litert_lm.Backend.GPU) ``` --- ## 🧪 Test nhanh ```bash # Kiểm tra server đang chạy curl http://localhost:8000/generate \ -X POST \ -H "Content-Type: application/json" \ -d '{"prompt": "Hello!"}' ``` --- ## 📝 Ghi chú - Mỗi session giữ toàn bộ lịch sử hội thoại trong RAM. Nên xóa session khi không dùng nữa. - Warning `mel_filterbank` khi khởi động là bình thường — liên quan đến audio encoder của Gemma 4 multimodal, không ảnh hưởng đến text generation. - Tốc độ generate phụ thuộc vào phần cứng. Trên Orange Pi 5 với CPU, khoảng 5–15 token/giây. - Token/s được đo bằng `engine.tokenize()` trên output thực tế — phản ánh đúng throughput của model, không bao gồm thời gian mạng. - Markdown được render bằng [marked.js](https://marked.js.org/) trực tiếp trên trình duyệt, không qua server. --- ## 📜 License MIT