# Triển khai trên Jetson

> Build, đóng gói và cài đặt X-Edge AI trên thiết bị NVIDIA Jetson — Orin, Xavier và dòng TX2 cũ.

X-Edge AI chạy trên các module NVIDIA Jetson (arm64 / L4T) với cùng bộ ba dịch vụ
như các box x86 — frontend, backend và dịch vụ suy luận Python. Điểm khác biệt
trên Jetson là **image suy luận**: nó phải được build dựa trên các thư viện
CUDA/TensorRT do JetPack cung cấp, với một wheel ONNX Runtime khớp với phiên bản
JetPack của bạn.

Triển khai Jetson được phát hành từ dòng release riêng **`Jetson-device`**. Các
cập nhật chảy một chiều từ dòng sản phẩm chính vào nó, nên các bản build Jetson
theo thiết kế luôn trễ hơn bản x86 mới nhất.

## Các profile được hỗ trợ

| Profile | Thiết bị / JetPack | Base image | ONNX Runtime | Execution provider |
|---|---|---|---|---|
| `jetson` | Orin / Xavier / Nano, JetPack 5+ (L4T r35+) | `l4t-base:r35.4.1` | JetPack wheel (theo từng thiết bị) | TensorRT → CUDA → CPU |
| `jetson-gpu` | TX2, JetPack 4.5 (L4T r32.5) | `l4t-base:r32.5.0` | `onnxruntime-gpu 1.10.0` (cp36 wheel) | CUDA (TensorRT EP không có trên JetPack 4.5) |
| `jetson-cpu` | Mọi Jetson arm64 | `python:3.11-slim` (arm64) | `onnxruntime` (CPU) | CPU |

Hai điểm cần biết về profile GPU của TX2 trước khi bắt đầu:

- **Giới hạn ONNX opset.** ONNX Runtime 1.10 hỗ trợ tối đa **opset 15**. Hãy xuất
  các mô hình dành cho TX2 với `--opset 15` (bundle đã kèm sẵn một mô hình opset-15
  vì lý do này). Các Jetson mới hơn chạy JetPack wheel hiện hành chấp nhận opset 17.
- **Bộ phụ thuộc Python 3.6 bị đóng băng.** JetPack 4.5 bị khóa ở Python 3.6, nên
  image `jetson-gpu` dùng một nhánh phụ thuộc legacy đã ghim phiên bản. Ưu tiên
  `jetson` (Orin/JetPack 5) cho các fleet mới.

## Điều kiện tiên quyết (trên Jetson)

Image được build **trực tiếp trên thiết bị** — cross-build image L4T dưới QEMU
không ổn định và không được hỗ trợ.

```bash
docker version              # >= 20.10
docker compose version      # Cần plugin Compose v2
sudo apt-get install -y zstd openssl
df -h ~                     # giữ trống vài GB (eMMC của TX2 nhỏ)
docker info | grep -i nvidia   # Profile GPU: phải có NVIDIA container runtime
```

Với các profile GPU, hãy chọn wheel ONNX Runtime khớp với phiên bản JetPack của bạn
từ [Jetson Zoo](https://elinux.org/Jetson_Zoo#ONNX_Runtime) — pip wheel
`onnxruntime-gpu` bản x86 **không** hoạt động trên Jetson (nó liên kết thư viện
CUDA x86; lỗi "missing library" khi khởi động là triệu chứng kinh điển).

## Build → đóng gói → cài đặt

```mermaid
flowchart LR
  A["build-release-images.sh\n(build + tag 3 images)"] --> B["build-release-bundle.sh\n(docker save → dist/&lt;profile&gt;-&lt;version&gt;/)"]
  B --> C["install.sh on the target\n(load images → compose up → seed admin)"]
  A -. "build host: Jetson, internet once" .-> B
  C -. "target host: air-gapped OK" .-> C
```

1. **Build các image** (trên Jetson dùng để build, cần internet một lần):

   ```bash
   # Profile GPU — truyền wheel ONNX Runtime khớp với JetPack
   ORT_WHEEL_URL="https://<jetson-zoo-wheel-for-your-jetpack>.whl" \
     ./scripts/build-release-images.sh <version> --profile jetson-gpu

   # Profile CPU — không cần wheel
   ./scripts/build-release-images.sh <version> --profile jetson-cpu
   ```

   Trước lần build GPU đầu tiên, hãy giảm rủi ro cho wheel và quyền truy cập GPU
   bằng script dò: `./scripts/spike-jetson-gpu.sh` (kiểm tra GO/NO-GO).

2. **Đóng gói bundle offline:**

   ```bash
   ./scripts/build-release-bundle.sh --profile jetson-gpu --version v<version>
   ```

   Đầu ra `dist/jetson-gpu-v<version>/` chứa kho image nén kèm manifest toàn vẹn,
   một file compose đúng cho Tegra, mô hình seed, và các script runbook
   `install.sh` / `update.sh` / `uninstall.sh` — cùng bố cục với bundle x86 mô tả
   trong [Cài đặt từ gói offline](/vi/install-deploy/offline-bundle-install/).

3. **Cài đặt trên thiết bị đích** (sao chép thư mục bundle qua USB/scp):

   ```bash
   cd dist/jetson-gpu-v<version>
   sudo ./install.sh                    # tự phát hiện arm64 và chấp nhận bundle jetson-*
   # sudo ./install.sh --with-systemd   # tùy chọn: khởi động cùng máy
   ```

   Trình cài đặt xác minh checksum của kho, nạp image, sinh JWT secret và mật khẩu
   admin duy nhất, khởi chạy stack, chờ trạng thái khỏe mạnh, rồi in URL bảng điều
   khiển và mật khẩu admin **một lần** — hãy lưu lại ngay.

4. **Xác minh suy luận GPU là thật:**

   ```bash
   docker compose -f compose/docker-compose.release.yml ps                   # 3 dịch vụ khỏe mạnh
   docker inspect aiboard-inference-real --format '{{.HostConfig.Runtime}}'  # kỳ vọng: nvidia
   docker logs aiboard-inference-real 2>&1 | grep -iE "CUDA EP|provider"     # CUDA/TensorRT EP đang hoạt động
   curl -s http://localhost:5000/api/system/metrics | grep -oE '"gpu"[^}]*}' # số liệu GPU thật
   ```

## Hành vi riêng của Tegra

Compose của bundle Jetson khác với bản x86 một cách có chủ đích:

- **`runtime: nvidia`** và chạy root bên trong container suy luận — bắt buộc để
  truy cập thiết bị GPU trên Tegra.
- **Mount `/sys`** — tải và nhiệt độ GPU đến từ Tegra sysfs (Jetson không có
  `nvidia-smi`), cấp dữ liệu cho panel GPU của bảng điều khiển.
- **Ghim `OPENBLAS_CORETYPE`** — tránh lỗi illegal-instruction của OpenBLAS trên
  các nhân Tegra.
- **Số liệu N/A theo từng trường** — các trường tình trạng mà Jetson không báo cáo
  được sẽ hiển thị **N/A** thay vì số 0 giả.

Việc chọn execution provider hoạt động giống như trên x86: `EXECUTION_MODE=auto`
thử TensorRT → CUDA → CPU và ghi cảnh báo nếu tụt cấp. Để đảm bảo cứng rằng box
không bao giờ âm thầm tụt xuống CPU, hãy đặt `EXECUTION_MODE=cuda` (hoặc
`tensorrt`) cùng `STRICT_EP=1` — dịch vụ khi đó sẽ từ chối khởi động thay vì tụt
cấp. Xem [Execution provider tụt xuống CPU](/vi/troubleshooting/execution-provider-fallback/).

Các bundle `jetson-gpu` / `jetson-cpu` đã được xác minh ở mức build và phòng lab;
việc kiểm thử end-to-end cuối cùng của bản cài air-gapped trên một TX2 sạch vẫn
đang tiến hành. Hãy giữ sẵn một console serial/SSH trong lần cài đặt đầu tiên trên
thiết bị.

## Đánh phiên bản trên dòng Jetson

Các bản phát hành Jetson chỉ được đánh phiên bản bằng file `VERSION` — dòng Jetson
không bao giờ tạo tag sản phẩm `v*`. Khi bạn thấy lệch phiên bản giữa panel About
của bảng điều khiển và bundle của mình, hãy so sánh với manifest của bundle, không
phải với Git tag. Xem [Phiên bản & Cập nhật](/vi/operate/versioning/).

## Nếu có gì đó sai

| Triệu chứng | Cách khắc phục |
|---|---|
| `unknown shorthand flag: 'f' in -f` | Thiếu plugin Compose v2 — `sudo apt-get install -y docker-compose-plugin` |
| `Cannot autolaunch D-Bus` khi build | Sự cố credential-helper ở chế độ headless — script build tự cô lập nó; với lệnh `docker` tùy biến, dùng thư mục `DOCKER_CONFIG` rỗng |
| Container GPU: `no CUDA-capable device` | Host thiếu NVIDIA container runtime, hoặc compose thiếu `runtime: nvidia` (compose của bundle đã đặt sẵn) |
| Suy luận thoát với lỗi thiếu thư viện | Sai wheel ONNX Runtime cho JetPack của bạn — chọn wheel khớp từ Jetson Zoo rồi build lại |
| `install.sh`: "profile does not match bundle" | Truyền `--profile jetson-gpu` (hoặc `jetson-cpu`) một cách tường minh — cả hai đều hợp lệ trên arm64 |
| Mô hình bị từ chối khi upload (TX2) | Mô hình xuất với opset > 15 — xuất lại với `--opset 15` cho ONNX Runtime 1.10 |

## Bước tiếp theo

  - [Cài đặt từ gói offline](/vi/install-deploy/offline-bundle-install/) — Runbook cài đặt air-gapped đầy đủ dùng chung cho mọi profile.
  - [Thiết lập phần cứng](/vi/install-deploy/hardware-setup/) — Các chế độ execution provider và điều kiện tiên quyết về mạng.
  - [Chuẩn bị mô hình với modelctl](/vi/configure/prepare-models/) — Xuất mô hình ONNX với opset đúng cho thiết bị của bạn.
  - [Lỗi GPU / CUDA](/vi/troubleshooting/gpu-cuda-error-500/) — Khắc phục khả năng nhìn thấy GPU và lỗi CUDA.
