VnRobo
Về chúng tôiBảng giáBlogLiên hệ
🇺🇸ENĐăng nhậpDùng thử miễn phí
🇺🇸EN
VnRobo logo

Hạ tầng AI cho robot công nghiệp thế hệ mới.

Sản phẩm

  • Tính năng
  • Bảng giá
  • Kiến thức
  • Dịch vụ

Công ty

  • Về chúng tôi
  • Blog
  • Liên hệ

Pháp lý

  • Chính sách bảo mật
  • Điều khoản sử dụng

© 2026 VnRobo. Bảo lưu mọi quyền.

Được tạo với♥tại Việt Nam
VnRobo
Về chúng tôiBảng giáBlogLiên hệ
🇺🇸ENĐăng nhậpDùng thử miễn phí
🇺🇸EN
  1. Trang chủ
  2. Blog
  3. unifolm-vla + Unitree G1 (Bài 5): deploy inference server, SSH tunnel, và locomotion song song
humanoidhumanoidvladeployfastapiunitree-g1whole-bodylocomotiontutorial

unifolm-vla + Unitree G1 (Bài 5): deploy inference server, SSH tunnel, và locomotion song song

Bài cuối series: khởi động FastAPI inference server, kết nối G1 qua SSH tunnel, gửi action commands, chạy arm VLA và locomotion đồng thời — kèm safety checklist và debug guide cho các lỗi thường gặp trên phần cứng thật.

Nguyễn Anh Tuấn7 tháng 6, 20269 phút đọcCập nhật: 14 thg 6, 2026
unifolm-vla + Unitree G1 (Bài 5): deploy inference server, SSH tunnel, và locomotion song song

unifolm-vla + Unitree G1 (Bài 5): deploy inference server, SSH tunnel, và locomotion song song

Đây là bài cuối của series unifolm-vla + Unitree G1. Bài trước đã có checkpoint. Bài này: deploy lên G1 thật, chạy inference, và kết hợp locomotion song song để có whole-body behavior.

Trước khi đọc: Deploy lên robot thật luôn có rủi ro. Làm theo đúng thứ tự: sim trước → test offline → test với robot ở chế độ an toàn → full deploy.

Kiến trúc deploy

[Workstation GPU]                [Unitree G1]
                                 
  FastAPI Server                  Robot SDK
  run_real_eval_server.py         (arm control)
  port 8777                  ←→   192.168.123.xxx
       ↑                          
  POST /act                        
  {image, state, instruction}     (leg control)
       ↓                          unitree_rl_gym
  {action: [28 joints]}           motion.pt

Ba luồng chạy song song:

  1. VLA inference (workstation): nhận ảnh → predict action → gửi lên G1
  2. Arm control (G1): nhận joint commands từ VLA, thực thi
  3. Locomotion (G1): chạy motion.pt policy độc lập, điều khiển chân

Bước 1: Khởi động inference server

conda activate unifolm
cd ~/unifolm_ws/unifolm-vla

# Với Approach A checkpoint (8-GPU full fine-tune)
python run_real_eval_server.py \
  --ckpt_path /home/user/checkpoints/unifolm_g1_pickplace/best_checkpoint.pt \
  --vlm_pretrained_path /home/user/models/Qwen2.5-VL-7B-Instruct \
  --unnorm_key new_embodiment \
  --host 0.0.0.0 \
  --port 8777 \
  --use_bf16

# Với Approach B checkpoint (LoRA single-GPU)
# Cần load LoRA weights trước khi start server
python run_real_eval_server.py \
  --ckpt_path /home/user/checkpoints/lora_g1_pickplace \
  --vlm_pretrained_path /home/user/models/Qwen2.5-VL-7B-Instruct \
  --lora_mode true \
  --unnorm_key new_embodiment \
  --host 0.0.0.0 \
  --port 8777 \
  --use_bf16

Terminal output khi server sẵn sàng:

Loading VLM from: /home/user/models/Qwen2.5-VL-7B-Instruct
Loading checkpoint: /home/user/checkpoints/unifolm_g1_pickplace/best_checkpoint.pt
Model loaded. VRAM usage: 14.3 GB / 24 GB
Starting FastAPI server on 0.0.0.0:8777
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8777 (Press CTRL+C to quit)

Verify server hoạt động:

# Test với dummy data
curl -X POST http://localhost:8777/act \
  -H "Content-Type: application/json" \
  -d '{
    "full_image": null,
    "state": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
               0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
    "instruction": "pick up the red cup"
  }'

# Response mong đợi (action values ngẫu nhiên vì image null):
# {"action": [0.12, -0.05, 0.33, ...], "timestamp": 1234567890.123}

Bước 2: Thiết lập robot client trên G1

G1 có onboard computer (Jetson Orin NX). Ta cần gửi HTTP requests từ onboard computer → workstation server.

SSH tunnel setup

Kết nối workstation và G1 cùng LAN, sau đó tạo tunnel:

# Trên workstation — biết IP của G1 onboard computer
# IP mặc định G1: 192.168.123.18 (có thể khác)

# Test kết nối
ping 192.168.123.18

# SSH vào G1 onboard computer
ssh [email protected]
# Password: thường là "123" hoặc xem docs G1 của bạn

Robot client script

Tạo script robot_client.py trên G1 onboard computer (hoặc workstation nếu dùng LAN trực tiếp):

"""
Robot client: nhận ảnh từ G1 camera, gửi đến inference server, 
nhận action, thực thi trên G1 arm.
"""

import requests
import numpy as np
import time
import base64
import cv2
from unitree_sdk2py.core.channel import ChannelFactory
from unitree_sdk2py.idl.unitree_hg.msg.dds_ import LowCmd_
import json

INFERENCE_SERVER = "http://192.168.1.100:8777"  # IP workstation
TASK_INSTRUCTION = "pick up the red cup"
CONTROL_FREQ_HZ = 5   # ~5Hz, phù hợp với VLM inference latency

def encode_image(frame: np.ndarray) -> str:
    """Encode camera frame to base64 string."""
    _, buffer = cv2.imencode('.jpg', frame, [cv2.IMWRITE_JPEG_QUALITY, 85])
    return base64.b64encode(buffer).decode('utf-8')

def get_joint_states(sdk_interface) -> list:
    """Đọc joint states hiện tại từ G1."""
    # Đọc 14 joints arm (7 trái + 7 phải) từ Unitree SDK
    state = sdk_interface.get_low_state()
    arm_joints = [state.motor_state[i].q for i in range(13, 27)]  # arm joint indices
    return arm_joints

def send_action(sdk_interface, actions: list):
    """Gửi joint commands đến G1 arm."""
    cmd = LowCmd_()
    
    # Map action predictions → G1 joint commands
    for i, joint_idx in enumerate(range(13, 27)):  # arm joints
        if i < len(actions):
            cmd.motor_cmd[joint_idx].q = float(actions[i])
            cmd.motor_cmd[joint_idx].kp = 60.0   # position gain
            cmd.motor_cmd[joint_idx].kd = 3.0    # velocity damping
            cmd.motor_cmd[joint_idx].dq = 0.0
            cmd.motor_cmd[joint_idx].tau = 0.0
    
    sdk_interface.publish_low_cmd(cmd)

def main():
    # Init G1 SDK
    ChannelFactory.Instance().Init(0, "eth0")
    # ... (khởi tạo SDK interface — xem unitree_sdk2py docs)
    
    # Init camera
    cap = cv2.VideoCapture(0)   # camera trái cổ tay
    
    print(f"Starting robot client. Instruction: '{TASK_INSTRUCTION}'")
    print(f"Server: {INFERENCE_SERVER}")
    
    period = 1.0 / CONTROL_FREQ_HZ
    
    while True:
        t_start = time.time()
        
        # 1. Đọc camera frame
        ret, frame = cap.read()
        if not ret:
            print("Camera error")
            continue
        
        # 2. Đọc joint states
        joint_states = get_joint_states(sdk_interface=None)  # placeholder
        
        # 3. Gửi đến inference server
        payload = {
            "full_image": encode_image(frame),
            "state": joint_states,
            "instruction": TASK_INSTRUCTION,
        }
        
        try:
            response = requests.post(
                f"{INFERENCE_SERVER}/act",
                json=payload,
                timeout=0.5   # 500ms timeout — nếu server chậm thì skip
            )
            
            if response.status_code == 200:
                result = response.json()
                actions = result["action"]
                # 4. Thực thi actions
                send_action(sdk_interface=None, actions=actions)
            else:
                print(f"Server error: {response.status_code}")
                
        except requests.exceptions.Timeout:
            print("Inference timeout — keeping last action")
        except requests.exceptions.ConnectionError:
            print("Cannot connect to inference server")
        
        # Rate control
        elapsed = time.time() - t_start
        sleep_time = period - elapsed
        if sleep_time > 0:
            time.sleep(sleep_time)

if __name__ == "__main__":
    main()

Chạy robot client:

# Trên G1 onboard computer hoặc workstation (cùng mạng LAN với G1)
python robot_client.py

Bước 3: Locomotion song song với motion.pt

Trong khi arm VLA đang chạy, locomotion có thể chạy song song qua G1 built-in locomotion SDK hoặc motion.pt từ unitree_rl_gym.

Option A: G1 built-in locomotion (đơn giản nhất)

G1 có locomotion controller built-in. Dùng Unitree App hoặc remote controller để điều khiển di chuyển, trong khi arm VLA policy tự điều khiển tay.

# Trên workstation — gửi locomotion velocity commands qua SDK
python -c "
from unitree_sdk2py.core.channel import ChannelFactory
from unitree_sdk2py.idl.unitree_hg.msg.dds_ import SportModeCmd_

ChannelFactory.Instance().Init(0, 'eth0')

# G1 đứng tại chỗ (locomotion mode = stand)
# arm VLA tự chạy song song
cmd = SportModeCmd_()
cmd.mode = 1   # stand mode
# publish cmd...
print('G1 standing, arm VLA running in parallel')
"

Option B: unitree_rl_gym motion.pt policy

Nếu muốn locomotion tùy chỉnh (đi lại trong khi arm hoạt động):

conda activate loco
cd ~/unifolm_ws/unitree_rl_gym

# Chạy pretrained motion.pt policy
python legged_gym/scripts/play.py \
  --task g1 \
  --load_run pretrained \
  --checkpoint motion

# Policy này điều khiển chân G1 (12 joints)
# Trong khi đó arm VLA (robot_client.py) điều khiển tay song song

Lưu ý quan trọng về running simultaneously:

Arm VLA (robot_client.py):
  → Gửi commands cho joints 13-26 (arm + gripper)
  → Frequency: ~5Hz
  
Locomotion (motion.pt):
  → Gửi commands cho joints 0-11 (legs) + 12 (waist)
  → Frequency: 200-500Hz

Hai hệ thống KHÔNG conflict nhau vì điều khiển joint indices khác nhau.

Safety checklist trước khi chạy trên G1 thật

TRƯỚC KHI KHỞI ĐỘNG:
[ ] E-stop (nút dừng khẩn cấp) đã test và trong tầm tay
[ ] G1 đứng trên nền phẳng, không có chướng ngại vật trong 1m
[ ] Joint position limits đã set trong robot_client.py (kp/kd hợp lý)
[ ] Inference server đang running và đã verify bằng curl test
[ ] Camera kết nối và frame rate ổn định (>10 FPS)

KHI CHẠY:
[ ] Quan sát G1 liên tục — không rời mắt
[ ] Có người thứ 2 sẵn sàng bấm E-stop nếu cần
[ ] Log terminal để debug nếu có lỗi

DỪNG KHI:
[ ] G1 mất thăng bằng hoặc dao động khớp
[ ] Joint torque vượt ngưỡng (kiểm tra qua SDK monitor)
[ ] Arm di chuyển không dự đoán được (policy hallucination)
[ ] Inference server timeout > 3 lần liên tiếp

Troubleshooting thường gặp

Server không nhận được ảnh (full_image: null)

Nguyên nhân: camera capture fail hoặc base64 encode lỗi
Debug: test capture riêng trước
import cv2
cap = cv2.VideoCapture(0)
ret, frame = cap.read()
print("Camera OK:", ret, "Frame shape:", frame.shape if ret else None)

Arm di chuyển giật cục không mượt

Nguyên nhân: inference latency không ổn định
Fix options:
1. Tăng kp/kd smoothing trong robot_client.py
2. Thêm exponential moving average cho action output:
alpha = 0.7   # EMA filter
smoothed_action = alpha * new_action + (1 - alpha) * prev_action
send_action(smoothed_action)
prev_action = smoothed_action

Policy không thực hiện đúng task

Checklist debug theo thứ tự:

1. Lighting có giống lúc training không? (đèn khác = visual distribution shift)
2. Vật thể có đúng vị trí không? (lệch quá nhiều = out-of-distribution)
3. Camera calibration còn đúng không? (wrist camera có bị xê dịch không?)
4. Instruction text có đúng với training instruction không?
5. Checkpoint có phải best checkpoint không? (kiểm tra val loss thấp nhất)

G1 arm tự reset về vị trí home sau vài giây

Nguyên nhân: safety timeout trong G1 SDK — nếu không nhận được command 
             trong N giây, arm tự về home position
Fix: đảm bảo robot_client.py gửi command liên tục (kể cả khi action = [0, 0, ...])

Tóm tắt toàn series

Sau 5 bài, bạn đã hoàn thành pipeline đầy đủ:

Bài Input Output Tools
1: Architecture — Hiểu kiến trúc 3 repos
2: Data collection G1 + Meta Quest 3 50+ JSON demos xr_teleoperate
3: Data pipeline JSON demos RLDS dataset unitree_IL_lerobot + unifolm-vla
4: Fine-tune RLDS dataset VLA checkpoint DeepSpeed / LoRA
5: Deploy (bài này) Checkpoint + G1 Robot thực hiện task FastAPI + Unitree SDK

Bước tiếp theo để cải thiện:

  1. Thêm data diversity: 200+ demos với variation ánh sáng, vị trí vật thể
  2. Multi-task: thu thập data cho nhiều task, train trên cùng 1 model
  3. Locomotion tích hợp sâu hơn: train policy biết đi đến vật thể trước khi nhặt
  4. Khi Unifolm-VLM-0 public: fine-tune lại từ checkpoint đó → performance tốt hơn ~15-20%

References

  • unifolm-vla GitHub
  • unitree_sdk2_python GitHub
  • unitree_rl_gym GitHub
  • FastAPI documentation

Khuyến nghị công cụ

Stack train/deploy cho VLA

Train trên cloud/workstation, deploy bản tối ưu xuống Jetson hoặc robot computer.

Cloud GPU for VLA / policy training Dùng cho imitation learning, diffusion policy, RL và fine-tuning model robotics. Xem cloud GPU → NVIDIA Jetson Orin NX / Orin Nano Máy deploy edge cho perception, logging và inference đã tối ưu. Xem Jetson → Hugging Face / robotics dataset hosting Lưu dataset, checkpoint và model card để workflow LeRobot/VLA dễ chia sẻ hơn. Xem platform →

Bài viết liên quan

  • Bài 4: Fine-tune unifolm-vla
  • Bài 1: Kiến trúc tổng thể unifolm-vla + G1
  • GR00T N1 + G1: Deploy GEAR+SONIC (approach khác)
NT

Nguyễn Anh Tuấn

Robotics & AI Engineer. Building VnRobo — sharing knowledge about robot learning, VLA models, and automation.

Khám phá VnRobo

Fleet MonitoringROS 2 IntegrationAMR Solutions
unifolm-vla-g1-series — Phần 5/5
← unifolm-vla + Unitree G1 (Bài 4): fine-tune từ Qwen2.5-VL-7B — 8-GPU và single-GPU LoRA

Bài viết liên quan

Tutorial
unifolm-vla + Unitree G1 (Bài 1): kiến trúc hệ thống WBC+VLA từ dữ liệu đến robot thật
humanoidvlawhole-bodyPhần 1
humanoid

unifolm-vla + Unitree G1 (Bài 1): kiến trúc hệ thống WBC+VLA từ dữ liệu đến robot thật

Tổng quan kiến trúc 3 repo — unifolm-vla (VLA), xr_teleoperate (thu thập dữ liệu), unitree_rl_gym (locomotion) — và cách chúng kết nối thành pipeline whole-body control cho Unitree G1 trên phần cứng thật.

31/5/20267 phút đọc
NT
Tutorial
unifolm-vla + Unitree G1 (Bài 4): fine-tune từ Qwen2.5-VL-7B — 8-GPU và single-GPU LoRA
humanoidvlafine-tuningPhần 4
humanoid

unifolm-vla + Unitree G1 (Bài 4): fine-tune từ Qwen2.5-VL-7B — 8-GPU và single-GPU LoRA

Hướng dẫn fine-tune unifolm-vla từ checkpoint công khai Qwen2.5-VL-7B-Instruct (vì Unifolm-VLM-0 chưa public) — gồm approach chính thức 8-GPU DeepSpeed và workaround single-GPU với QLoRA cho beginner.

6/6/20268 phút đọc
NT
Tutorial
GR00T N1 + G1 (Bài 4): deploy GR00T-WBC trên Unitree G1 — GEAR + SONIC
humanoidvlawhole-bodyPhần 4
humanoid

GR00T N1 + G1 (Bài 4): deploy GR00T-WBC trên Unitree G1 — GEAR + SONIC

Hướng dẫn deploy GR00T-WBC stack (GEAR upper body 50Hz + SONIC locomotion 200Hz) trên Unitree G1 với checkpoint GR00T N1 đã fine-tune — joint mapping, PD tuning, safety, và adapt cho robot khác.

5/6/20266 phút đọc
NT
VnRobo logo

Hạ tầng AI cho robot công nghiệp thế hệ mới.

Sản phẩm

  • Tính năng
  • Bảng giá
  • Kiến thức
  • Dịch vụ

Công ty

  • Về chúng tôi
  • Blog
  • Liên hệ

Pháp lý

  • Chính sách bảo mật
  • Điều khoản sử dụng

© 2026 VnRobo. Bảo lưu mọi quyền.

Được tạo với♥tại Việt Nam