update README and SERVICE

This commit is contained in:
2026-04-20 20:59:51 +07:00
parent 4b1fd185d7
commit 89fbac3177
5 changed files with 640 additions and 27 deletions
+71 -17
View File
@@ -45,8 +45,8 @@ huggingface_hub
| Model | Repo HuggingFace | Mô tả |
|-------|-----------------|-------|
| `gemma-4-E2B-it` | [google/gemma-4-E2B-it](https://huggingface.co/google/gemma-4-E2B-it) | Edge 2B — nhanh hơn, nhẹ hơn |
| `gemma-4-E4B-it` | [google/gemma-4-E4B-it](https://huggingface.co/google/gemma-4-E4B-it) | Edge 4B — thông minh hơn, nặng hơn |
| `gemma-4-E2B-it` | [litert-community/gemma-4-E2B-it-litert-lm](https://huggingface.co/litert-community/gemma-4-E2B-it-litert-lm) | Edge 2B — nhanh hơn, nhẹ hơn |
| `gemma-4-E4B-it` | [litert-community/gemma-4-E4B-it-litert-lm](https://huggingface.co/litert-community/gemma-4-E4B-it-litert-lm) | Edge 4B — thông minh hơn, nặng hơn |
> **Lưu ý:** Nên dùng bản `-it` (instruction-tuned) cho chat/hỏi đáp. Bản không có `-it` là base model, chỉ predict token tiếp theo, không phù hợp để hội thoại.
@@ -54,25 +54,23 @@ huggingface_hub
```bash
# Gemma 4 E2B (nhỏ hơn, ~nhanh hơn)
huggingface-cli download google/gemma-4-E2B-it \
hf download litert-community/gemma-4-E2B-it-litert-lm \
--include '*.litertlm' \
--local-dir models/
# Gemma 4 E4B (lớn hơn, ~thông minh hơn)
huggingface-cli download google/gemma-4-E4B-it \
hf download litert-community/gemma-4-E4B-it-litert-lm \
--include '*.litertlm' \
--local-dir models/
```
> **Hoặc** để server tự động tải khi chọn model chưa có sẵn.
---
## 🚀 Hướng dẫn sử dụng
### Bước 1 — Tải ít nhất một model vào thư mc `models/`
Xem lệnh tải ở trên.
### Bước 2 — Chạy server
### Cách 1: Chạy với tùy chọn mc định
```bash
python server.py
@@ -92,18 +90,51 @@ Server sẽ hiển thị menu **chọn model** trước khi khởi động:
Gemma 4 Edge 4B — thông minh hơn, chậm hơn
✗ chưa tải
Chọn model (1/2):
[3] Sử dụng model từ đường dẫn khác
Chọn model (1/2/3):
```
Nếu model chưa được tải, server sẽ hiển thị lệnh `huggingface-cli download` tương ứng và hỏi có muốn chọn model khác không.
**Tính năng tự động tải model:**
- Nếu chọn model chưa có, server sẽ hỏi: `Bạn muốn tải model ngay bây giờ? (y/n)`
- Chọn `y` để tự động tải từ Hugging Face
- Hoặc chọn `n` để tải thủ công sau
### Bước 3 — Mở Web UI
**Tự động xử lý port:**
- Nếu port 8000 đã bị chiếm, server sẽ hỏi chọn port khác
- Hoặc nhấn Enter để tự động tìm port khả dụng (8001-8999)
```
http://<địa-chỉ-ip>:8000
### Cách 2: Chạy với tham số command line
```bash
# Chỉ định port
python server.py --port 8080
# Chỉ định model từ đường dẫn
python server.py --model /path/to/model.litertlm
# Kết hợp cả hai
python server.py --port 8080 --model ~/models/gemma-4-E2B-it.litertlm
# Xem hướng dẫn đầy đủ
python server.py --help
```
Tên model đang chạy sẽ hiển thị trên header của Web UI.
### Mở Web UI
```
http://<địa-chỉ-ip>:<port>
```
Tên model và port sẽ hiển thị khi server khởi động:
```
====================================================
🚀 Server đang khởi động...
📍 URL: http://localhost:8000
📦 Model: gemma-4-E2B-it.litertlm
====================================================
```
---
@@ -307,6 +338,16 @@ curl -X DELETE http://localhost:8000/chat/$SESSION
## ⚙️ Cấu hình
### Tham số command line
| Tham số | Mô tả | Mặc định |
|---------|-------|---------|
| `--port`, `-p` | Port để chạy server | `8000` |
| `--model`, `-m` | Đường dẫn đầy đủ tới file model .litertlm | None (chọn từ menu) |
| `--help`, `-h` | Hiển thị hướng dẫn | - |
### Cấu hình trong code
Các tham số chỉnh trong đầu `server.py`:
| Biến | Mô tả | Mặc định |
@@ -315,7 +356,6 @@ Các tham số chỉnh trong đầu `server.py`:
| `AVAILABLE_MODELS` | Danh sách model + repo HuggingFace | xem trong file |
| `backend` | Backend inference | `litert_lm.Backend.CPU` |
| `host` | Địa chỉ lắng nghe | `0.0.0.0` |
| `port` | Cổng | `8000` |
Để thêm model mới vào menu, bổ sung vào dict `AVAILABLE_MODELS` trong `server.py`:
@@ -323,7 +363,7 @@ Các tham số chỉnh trong đầu `server.py`:
AVAILABLE_MODELS = {
"gemma-4-E2B-it": {
"file": "gemma-4-E2B-it.litertlm",
"repo": "google/gemma-4-E2B-it",
"repo": "litert-community/gemma-4-E2B-it-litert-lm",
"desc": "Gemma 4 Edge 2B — nhỏ hơn, nhanh hơn",
},
"ten-model-moi": {
@@ -340,6 +380,20 @@ AVAILABLE_MODELS = {
engine = litert_lm.Engine(str(MODEL_PATH), backend=litert_lm.Backend.GPU)
```
### Chạy như systemd service (Linux)
Xem hướng dẫn chi tiết trong [SERVICE_README.md](SERVICE_README.md)
```bash
# Cài đặt service
sudo bash install_service.sh
# Quản lý service
sudo systemctl status litert-lm
sudo systemctl restart litert-lm
sudo journalctl -u litert-lm -f
```
---
## 📝 Ghi chú
+415
View File
@@ -0,0 +1,415 @@
# LiteRT-LM Linux Systemd Service
Hướng dẫn cài đặt và sử dụng LiteRT-LM server như một systemd service trên Linux.
## 📋 Yêu cầu
- Linux với systemd (Ubuntu, Debian, Fedora, CentOS, etc.)
- Python 3 đã cài đặt
- Quyền sudo
## 🚀 Cài đặt Service
### Bước 1: Cho phép thực thi script
```bash
chmod +x install_service.sh uninstall_service.sh
```
### Bước 2: Chạy script cài đặt
```bash
sudo bash install_service.sh
```
Script sẽ hỏi cấu hình:
- **Port**: Port để chạy server (mặc định 8000)
- **Model path**: Đường dẫn model cụ thể (hoặc Enter để chọn từ menu)
Sau đó script sẽ:
1. Tạo file config model mặc định (nếu cần)
2. Tạo systemd service file với cấu hình đã chọn
3. Enable service để tự động khởi động khi boot
4. Khởi động service ngay lập tức
## ⚙️ Cấu hình
### Cấu hình Model
**Cách 1: Chọn từ menu (mặc định)**
Chỉnh sửa file `service_config.txt` để chọn model:
```
1 → Gemma 4 Edge 2B (nhanh hơn)
2 → Gemma 4 Edge 4B (thông minh hơn)
3 → Nhập đường dẫn tùy chỉnh
```
Sau khi thay đổi, restart service:
```bash
sudo systemctl restart litert-lm
```
**Cách 2: Chỉ định model cụ thể**
Chỉnh sửa file service:
```bash
sudo nano /etc/systemd/system/litert-lm.service
```
Sửa dòng `ExecStart`:
```ini
ExecStart=/usr/bin/python3 /path/to/server.py --model /path/to/model.litertlm
```
Sau đó:
```bash
sudo systemctl daemon-reload
sudo systemctl restart litert-lm
```
### Cấu hình Port
Chỉnh sửa file service:
```bash
sudo nano /etc/systemd/system/litert-lm.service
```
Sửa dòng `ExecStart`:
```ini
# Chỉ port
ExecStart=/usr/bin/python3 /path/to/server.py --port 8080
# Hoặc kết hợp với model
ExecStart=/usr/bin/python3 /path/to/server.py --port 8080 --model /path/to/model.litertlm
```
Sau đó:
```bash
sudo systemctl daemon-reload
sudo systemctl restart litert-lm
```
## 🎮 Quản lý Service
### Xem trạng thái
```bash
sudo systemctl status litert-lm
```
### Dừng service
```bash
sudo systemctl stop litert-lm
```
### Khởi động service
```bash
sudo systemctl start litert-lm
```
### Khởi động lại service
```bash
sudo systemctl restart litert-lm
```
### Xem logs realtime
```bash
sudo journalctl -u litert-lm -f
```
### Xem logs từ đầu
```bash
sudo journalctl -u litert-lm
```
### Xem logs 100 dòng cuối
```bash
sudo journalctl -u litert-lm -n 100
```
### Gỡ cài đặt service
```bash
sudo bash uninstall_service.sh
```
## 📊 Kiểm tra Service
### Kiểm tra service đang chạy
```bash
sudo systemctl is-active litert-lm
```
### Kiểm tra server hoạt động
Mở trình duyệt: http://localhost:8000 (hoặc port đã cấu hình)
Hoặc test API:
```bash
curl http://localhost:8000/info
```
## 🔧 Cấu hình nâng cao
### Chỉnh sửa service file
```bash
sudo nano /etc/systemd/system/litert-lm.service
```
Sau khi chỉnh sửa:
```bash
sudo systemctl daemon-reload
sudo systemctl restart litert-lm
```
### Thay đổi user chạy service
Trong file service, sửa dòng:
```ini
User=your_username
```
### Thêm biến môi trường
Thêm vào section `[Service]`:
```ini
Environment="VARIABLE_NAME=value"
Environment="ANOTHER_VAR=value"
```
### Giới hạn tài nguyên
Thêm vào section `[Service]`:
```ini
# Giới hạn memory (ví dụ: 2GB)
MemoryLimit=2G
# Giới hạn CPU (ví dụ: 50%)
CPUQuota=50%
```
## 🔍 Troubleshooting
### Service không khởi động
1. Kiểm tra logs:
```bash
sudo journalctl -u litert-lm -n 50
```
2. Kiểm tra file service:
```bash
sudo systemctl cat litert-lm
```
3. Kiểm tra syntax:
```bash
sudo systemd-analyze verify /etc/systemd/system/litert-lm.service
```
### Thay đổi đường dẫn hoặc cấu hình
Chỉnh sửa file service:
```bash
sudo nano /etc/systemd/system/litert-lm.service
```
Sửa các dòng:
- `WorkingDirectory=` - Đường dẫn thư mục project
- `ExecStart=` - Lệnh khởi động với tham số
- `StandardInput=` - Đường dẫn file config
Sau đó:
```bash
sudo systemctl daemon-reload
sudo systemctl restart litert-lm
```
### Service bị crash
Service sẽ tự động restart sau 10 giây nhờ cấu hình:
```ini
Restart=always
RestartSec=10
```
### Thay đổi port
Sử dụng tham số `--port`:
```bash
sudo nano /etc/systemd/system/litert-lm.service
```
Sửa dòng `ExecStart`:
```ini
ExecStart=/usr/bin/python3 /path/to/server.py --port 8080
```
Sau đó:
```bash
sudo systemctl daemon-reload
sudo systemctl restart litert-lm
```
### Permission denied
Đảm bảo user trong service file có quyền đọc/ghi thư mục:
```bash
sudo chown -R your_username:your_username /path/to/litert-lm-orangepi
```
## 🔐 Bảo mật
### Chạy service với user riêng
Tạo user chuyên dụng:
```bash
sudo useradd -r -s /bin/false litert-lm
sudo chown -R litert-lm:litert-lm /path/to/litert-lm-orangepi
```
Sửa trong service file:
```ini
User=litert-lm
Group=litert-lm
```
### Giới hạn quyền truy cập
Thêm vào section `[Service]`:
```ini
# Chỉ đọc /usr, /boot, /etc
ProtectSystem=full
# Không cho ghi vào /home
ProtectHome=true
# Không cho truy cập /dev
PrivateDevices=true
```
### Firewall
Chỉ cho phép truy cập local:
```bash
sudo ufw allow from 127.0.0.1 to any port 8000
```
Hoặc cho phép từ mạng nội bộ:
```bash
sudo ufw allow from 192.168.1.0/24 to any port 8000
```
## 📦 Cấu trúc Files
```
litert-lm-orangepi/
├── server.py # Server chính (hỗ trợ --port và --model)
├── install_service.sh # Script cài đặt service
├── uninstall_service.sh # Script gỡ cài đặt service
├── litert-lm.service # Template systemd service
├── service_config.txt # Config model (1/2/3) - dùng khi không chỉ định --model
├── SERVICE_README.md # File này
└── models/ # Thư mục chứa models
├── gemma-4-E2B-it.litertlm
└── gemma-4-E4B-it.litertlm
```
## 🎯 Auto-start khi khởi động
Service đã được cấu hình để tự động khởi động:
```bash
# Kiểm tra
sudo systemctl is-enabled litert-lm
# Tắt auto-start
sudo systemctl disable litert-lm
# Bật auto-start
sudo systemctl enable litert-lm
```
## 📊 Monitoring
### Xem resource usage
```bash
systemctl status litert-lm
```
### Xem chi tiết hơn
```bash
sudo systemd-cgtop
```
### Xem tất cả services
```bash
systemctl list-units --type=service
```
## ✅ Checklist sau khi cài đặt
- [ ] Service đã được cài đặt: `systemctl list-units | grep litert-lm`
- [ ] Service đang chạy: `systemctl is-active litert-lm`
- [ ] Có thể truy cập http://localhost:8000 (hoặc port đã cấu hình)
- [ ] API `/info` trả về thông tin model
- [ ] Service tự động khởi động: `systemctl is-enabled litert-lm`
- [ ] Logs hiển thị bình thường: `journalctl -u litert-lm -n 20`
## 🆘 Các lệnh hữu ích
```bash
# Xem toàn bộ config của service
sudo systemctl show litert-lm
# Xem dependencies
systemctl list-dependencies litert-lm
# Xem thời gian khởi động
systemd-analyze blame
# Test service file syntax
sudo systemd-analyze verify /etc/systemd/system/litert-lm.service
# Xem logs từ boot cuối cùng
sudo journalctl -u litert-lm -b
# Xem logs trong khoảng thời gian
sudo journalctl -u litert-lm --since "1 hour ago"
sudo journalctl -u litert-lm --since "2024-01-01" --until "2024-01-02"
# Export logs ra file
sudo journalctl -u litert-lm > litert-lm.log
```
## 🔄 Update service
Khi có thay đổi code trong `server.py`:
```bash
sudo systemctl restart litert-lm
```
Không cần cài đặt lại service.
## 📝 Ghi chú
- Service sử dụng `StandardInput=file:` để tự động truyền model choice từ `service_config.txt` (nếu không dùng `--model`)
- Logs được quản lý bởi systemd journal (journalctl)
- Service tự động restart nếu bị crash
- Có thể chạy nhiều instance với port khác nhau bằng cách tạo nhiều service file
- Tham số `--port``--model` cho phép linh hoạt cấu hình mà không cần chỉnh sửa code
+29 -4
View File
@@ -18,14 +18,31 @@ if [ "$EUID" -ne 0 ]; then
exit 1
fi
# Tạo file config model mặc định nếu chưa có
if [ ! -f "service_config.txt" ]; then
# Hỏi cấu hình
echo "Cấu hình service:"
echo
# Port
read -p "Port (mặc định 8000): " SERVICE_PORT
SERVICE_PORT=${SERVICE_PORT:-8000}
# Model path (tùy chọn)
read -p "Đường dẫn model (Enter để chọn từ menu khi khởi động): " MODEL_PATH
if [ -n "$MODEL_PATH" ]; then
MODEL_ARG="--model $MODEL_PATH"
else
MODEL_ARG=""
fi
# Tạo file config model mặc định nếu chưa có và không dùng custom model
if [ -z "$MODEL_PATH" ] && [ ! -f "service_config.txt" ]; then
echo "1" > service_config.txt
chown $SUDO_USER:$SUDO_USER service_config.txt
echo "[✓] Đã tạo service_config.txt với model mặc định: 1"
fi
# Tạo file service từ template
echo
echo "[1/4] Tạo file systemd service..."
cat > /tmp/litert-lm.service << EOF
[Unit]
@@ -37,7 +54,7 @@ Type=simple
User=$SUDO_USER
WorkingDirectory=$CURRENT_DIR
Environment="PATH=/usr/bin:/usr/local/bin:$HOME/.local/bin"
ExecStart=$PYTHON_PATH $CURRENT_DIR/server.py
ExecStart=$PYTHON_PATH $CURRENT_DIR/server.py --port $SERVICE_PORT $MODEL_ARG
StandardInput=file:$CURRENT_DIR/service_config.txt
Restart=always
RestartSec=10
@@ -68,6 +85,14 @@ echo
echo "Service đã được cài đặt và khởi động."
echo "Server sẽ tự động chạy khi khởi động hệ thống."
echo
echo "Cấu hình:"
echo " - Port: $SERVICE_PORT"
if [ -n "$MODEL_PATH" ]; then
echo " - Model: $MODEL_PATH"
else
echo " - Model: Chọn từ menu (xem service_config.txt)"
fi
echo
echo "Các lệnh quản lý:"
echo " - Xem trạng thái: sudo systemctl status litert-lm"
echo " - Dừng service: sudo systemctl stop litert-lm"
@@ -76,7 +101,7 @@ echo " - Khởi động lại: sudo systemctl restart litert-lm"
echo " - Xem logs: sudo journalctl -u litert-lm -f"
echo " - Gỡ cài đặt: sudo bash uninstall_service.sh"
echo
echo "Server đang chạy tại: http://localhost:8000"
echo "Server đang chạy tại: http://localhost:$SERVICE_PORT"
echo
# Hiển thị trạng thái
+7
View File
@@ -7,7 +7,14 @@ Type=simple
User=your_username
WorkingDirectory=/home/your_username/litert-lm-orangepi
Environment="PATH=/usr/bin:/usr/local/bin"
# Tùy chọn 1: Chạy với port mặc định, chọn model từ menu
ExecStart=/usr/bin/python3 /home/your_username/litert-lm-orangepi/server.py
# Tùy chọn 2: Chỉ định port
# ExecStart=/usr/bin/python3 /home/your_username/litert-lm-orangepi/server.py --port 8080
# Tùy chọn 3: Chỉ định model cụ thể
# ExecStart=/usr/bin/python3 /home/your_username/litert-lm-orangepi/server.py --model /path/to/model.litertlm
# Tùy chọn 4: Kết hợp cả hai
# ExecStart=/usr/bin/python3 /home/your_username/litert-lm-orangepi/server.py --port 8080 --model /path/to/model.litertlm
StandardInput=file:/home/your_username/litert-lm-orangepi/service_config.txt
Restart=always
RestartSec=10
+118 -6
View File
@@ -2,6 +2,8 @@ import os
import sys
import uuid
import time
import socket
import argparse
from pathlib import Path
# Suppress verbose logs
@@ -34,6 +36,49 @@ AVAILABLE_MODELS = {
# ── CLI: chọn model khi khởi động ────────────────────────────────────────────
def is_port_available(port: int) -> bool:
"""Kiểm tra xem port có khả dụng không."""
try:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind(("0.0.0.0", port))
return True
except OSError:
return False
def select_port(default_port: int = 8000) -> int:
"""Chọn port khả dụng."""
if is_port_available(default_port):
return default_port
print(f"\n ⚠️ Port {default_port} đã bị chiếm!")
while True:
try:
choice = input(f" Nhập port khác (hoặc Enter để dùng port tự động): ").strip()
if not choice:
# Tìm port tự động
for port in range(8001, 9000):
if is_port_available(port):
print(f" ✓ Sử dụng port tự động: {port}")
return port
print(" ✗ Không tìm thấy port khả dụng trong khoảng 8001-8999")
continue
port = int(choice)
if port < 1024 or port > 65535:
print(" ✗ Port phải trong khoảng 1024-65535")
continue
if is_port_available(port):
print(f" ✓ Sử dụng port: {port}")
return port
else:
print(f" ✗ Port {port} đã bị chiếm, vui lòng chọn port khác")
except ValueError:
print(" ✗ Vui lòng nhập số port hợp lệ")
except KeyboardInterrupt:
print("\n Thoát.")
sys.exit(0)
def download_model(repo: str, local_dir: Path) -> bool:
"""Tải model từ Hugging Face về local."""
try:
@@ -61,7 +106,20 @@ def download_model(repo: str, local_dir: Path) -> bool:
print(f"\n ✗ Lỗi không xác định: {e}")
return False
def select_model() -> Path:
def select_model(custom_path: str = None) -> Path:
"""Chọn model để sử dụng."""
# Nếu có custom path, kiểm tra và sử dụng luôn
if custom_path:
custom_model = Path(custom_path)
if custom_model.exists() and custom_model.suffix == ".litertlm":
print(f"\n ✓ Sử dụng model từ đường dẫn: {custom_model}")
return custom_model
else:
print(f"\n ✗ Không tìm thấy model tại: {custom_path}")
print(f" Vui lòng kiểm tra lại đường dẫn.\n")
sys.exit(1)
print("\n" + "="*52)
print(" LiteRT-LM Server — Chọn model")
print("="*52)
@@ -73,10 +131,30 @@ def select_model() -> Path:
print(f" {info['desc']}")
print(f" {status}")
print()
print(f" [3] Sử dụng model từ đường dẫn khác")
print()
while True:
try:
choice = input("Chọn model (1/2): ").strip()
choice = input("Chọn model (1/2/3): ").strip()
# Tùy chọn 3: Đường dẫn tùy chỉnh
if choice == "3":
custom_path = input("\n Nhập đường dẫn đầy đủ tới file .litertlm: ").strip()
custom_model = Path(custom_path)
if custom_model.exists() and custom_model.suffix == ".litertlm":
print(f"\n Đã chọn: {custom_model.name}")
print(f" Path: {custom_model}\n")
return custom_model
else:
print(f"\n ✗ Không tìm thấy file model hợp lệ tại: {custom_path}")
retry = input(" Thử lại? (y/n): ").strip().lower()
if retry == "y":
continue
else:
sys.exit(0)
idx = int(choice) - 1
if 0 <= idx < len(AVAILABLE_MODELS):
key = list(AVAILABLE_MODELS.keys())[idx]
@@ -122,14 +200,43 @@ def select_model() -> Path:
print(f" Path: {model_path}\n")
return model_path
else:
print(" Vui lòng nhập 1 hoặc 2.")
print(" Vui lòng nhập 1, 2 hoặc 3.")
except (ValueError, KeyboardInterrupt):
print("\n Thoát.")
sys.exit(0)
# Chọn model trước khi FastAPI khởi động
# Parse command line arguments
def parse_args():
parser = argparse.ArgumentParser(
description="LiteRT-LM Server - Local AI inference server",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Ví dụ:
python server.py
python server.py --port 8080
python server.py --model /path/to/model.litertlm
python server.py --port 8080 --model /path/to/model.litertlm
"""
)
parser.add_argument(
"--port", "-p",
type=int,
default=8000,
help="Port để chạy server (mặc định: 8000)"
)
parser.add_argument(
"--model", "-m",
type=str,
default=None,
help="Đường dẫn đầy đủ tới file model .litertlm"
)
return parser.parse_args()
# Parse arguments và chọn model trước khi FastAPI khởi động
args = parse_args()
MODELS_DIR.mkdir(exist_ok=True)
MODEL_PATH = select_model()
MODEL_PATH = select_model(args.model)
SERVER_PORT = select_port(args.port)
# ── Models ───────────────────────────────────────────────────────────────────
@@ -263,4 +370,9 @@ async def web_ui():
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
print(f"\n{'='*52}")
print(f" 🚀 Server đang khởi động...")
print(f" 📍 URL: http://localhost:{SERVER_PORT}")
print(f" 📦 Model: {MODEL_PATH.name}")
print(f"{'='*52}\n")
uvicorn.run(app, host="0.0.0.0", port=SERVER_PORT)