เราทำอะไรอยู่?
โครงการนี้คือการพัฒนา Model OCR สำหรับอ่านป้ายทะเบียนรถภาษาไทย เพื่อใช้กับกล้อง AI ที่ติดตั้งบน Raspberry Pi 5 + Hailo-8 M.2 HAT สำหรับงานเฝ้าตรวจชายแดน
ปัญหาตั้งต้น: Hailo LPRNet ที่มีมาให้ใน Model Zoo ถูก train ด้วยตัวอักษร Latin ทั้งหมด — ไม่รู้จักภาษาไทยเลยแม้แต่ตัวเดียว เราเลยต้อง Fine-Tune ใหม่ด้วย dataset ป้ายทะเบียนไทยที่สร้างแบบ Synthetic ขึ้นมาเอง
ขั้นตอน: สร้าง dataset 100,000+ ภาพ → train บน Jetson AGX Xavier → export ONNX → compile เป็น HEF สำหรับ Hailo-8 → deploy บน RPi5

ปัญหาที่เจอ: Mac หลับ → Training พัง
Workflow ของเรา: นั่งทำงานบน Macbook ที่บ้าน แล้ว SSH เข้า Jetson AGX Xavier ผ่าน Tailscale Network ซึ่งปกติทำงานได้ดีมาก
แต่เมื่อ Mac เข้าสู่โหมด sleep — SSH connection ก็ถูกตัด ทำให้ terminal session บน Jetson ตายตามไปด้วย SIGHUP signal ส่งไปยัง process การ train ทำให้ Training หยุดทันที แม้ว่า loss กำลังลดลงดีอยู่ก็ตาม
การ train ภาพ 100,000 ภาพใช้เวลาหลายสิบชั่วโมง — การนั่งเฝ้าหน้าจอตลอดหรือเปิด Mac ทิ้งไว้โดยไม่ให้หลับนั้นไม่ practical เลย
วิธีแก้: tmux — Virtual Terminal ที่ไม่ตายตาม SSH
tmux สร้าง Virtual Terminal Session บน Jetson ที่มีชีวิตอยู่อิสระจาก SSH connection — ไม่ว่า Mac จะหลับ, ปิดฝา, หรือ Tailscale ขาดชั่วคราว กระบวนการ Training ยังรันต่อเนื่อง แล้วค่อย reconnect มาดูผลได้ตอนตื่นนอน
ปกติ process บน Jetson ผูกกับ SSH session — SSH session ตาย process ตายตาม แต่ถ้าเราใช้ tmux สร้าง session ไว้ก่อน แล้วรัน training ข้างใน tmux — process จะผูกกับ tmux ไม่ใช่ SSH อีกต่อไป

ขั้นตอนจริง
1. ติดตั้ง tmux บน Jetson (ทำครั้งเดียว)
ssh agx-tail
sudo apt update && sudo apt install -y tmux
2. เริ่ม Training Session ใหม่
# สร้าง session ชื่อ "train"
tmux new -s train
# ภายใน tmux — activate venv แล้ว run training
cd ~/hailo_model_zoo/hailo_models/license_plate_recognition
source .venv/bin/activate
python train_lprnet.py --train_dir dataset_thai/train --test_dir dataset_thai/test --max_epochs 50 --train_batch_size 32 --output_dir ./models --device cuda
3. Detach ออก — แล้วปิดฝา Mac ได้เลย
# กด Ctrl+B แล้วตามด้วย D เพื่อ detach
[detached (from session train)]
# ตอนนี้ Mac นอนหลับได้ — training ยังรันต่อเนื่องบน Jetson
4. ตื่นนอนตอนเช้า — กลับมา attach ดูผล
ssh agx-tail
tmux attach -t train
# เห็น output training ครบ:
Training Epoch 48 | Train Loss: 0.0821 | Val Loss: 0.0943
Epoch 48 | Val Accuracy: 89.40%
Training complete! Model saved to ./models/
คำสั่ง tmux ที่ใช้บ่อย
- tmux new -s train — สร้าง session ใหม่ชื่อ train
- Ctrl+B → D — Detach ออกจาก session (training ยังรัน)
- tmux attach -t train — กลับเข้า session เดิม เห็น output ทุก line
- tmux ls — ดูรายชื่อ session ที่รันอยู่ทั้งหมด
- tmux kill-session -t train — ลบ session (หลัง training เสร็จ)
- Ctrl+B → [ — Scroll mode ใช้ scroll ดู log ย้อนหลัง
ผลลัพธ์จริงจาก Training Run แรก
Dataset ที่สร้างด้วย synthetic_thai_plates.py และ Training run แรกให้ผลดังนี้:
- Dataset train: 100,010 ภาพ
- Dataset test: 10,010 ภาพ
- Generate time: 8:39 นาที
- Storage (train set): 918 MB
- Epoch 1 Train Loss: 1.4617
- Epoch 3 Train Loss: 1.0156 ↓ (ลดลงอย่างต่อเนื่อง)
หมายเหตุ: Epoch 1-3 Val Accuracy ยังเป็น 0% เพราะโมเดลเพิ่งเริ่มเรียนรู้ charset ภาษาไทยซึ่งต่างจาก pretrained weight มาก คาดว่า accuracy จะเริ่มขึ้นหลัง epoch 10+

โบนัส: ป้องกัน SSH หลุดระหว่าง Idle
แม้ tmux จะจัดการ Mac sleep ได้แล้ว แต่ถ้า SSH idle นานๆ บาง Router อาจตัด connection กลาง session ได้ แก้ง่ายๆ ด้วย SSH config บน MacBook:
Host agx-tail
HostName 100.100.137.9
User agx
ServerAliveInterval 60 # ping ทุก 60 วินาที
ServerAliveCountMax 10
TCPKeepAlive yes
"tmux บน Jetson เป็นวิธีที่ ML Engineers ทั่วโลกใช้สำหรับ Training ข้ามคืนบน Remote Server — เรียบง่าย แต่เปลี่ยนชีวิตการทำงานไปเลย"
Tags: #tmux #jetson-agx-xavier #lprnet #thai-ocr #hailo-8 #ml-training #tailscale #raspberry-pi-5 #edge-ai