File size: 8,953 Bytes
6603bc6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
---
license: apache-2.0
tags:
  - robotics
  - deployment
  - inference
  - cyclo-intelligence
  - ffw-sg2
  - lerobot
  - gr00t
pretty_name: cyclo_intelligence 배포 가이드 (FFW_SG2)
---

# cyclo_intelligence 배포 — 처음부터 끝까지

학습한 정책(LeRobot ACT/VQ-BeT/Diffusion 또는 GR00T N1.7)을 ROBOTIS **cyclo_intelligence** 웹 UI로
로봇에 올려 실행하는 전 과정. **실전에서 실제로 겪은 함정까지** 반영했다.

> 학습 파이프라인은 → LeRobot [`humanoid-imitation-learning`](https://huggingface.co/JSHNSL/humanoid-imitation-learning) · GR00T [`gr00t-ffw-sg2-finetune`](https://huggingface.co/JSHNSL/gr00t-ffw-sg2-finetune)

---

## 큰 그림

cyclo_intelligence는 여러 컨테이너로 구성된다:

| 컨테이너 | 역할 |
|----------|------|
| `cyclo_intelligence` | 오케스트레이터 + 웹 UI (nginx) |
| `lerobot_server` | **LeRobot 정책** 추론 엔진 (`robotis/lerobot-zenoh`) |
| `groot_server` | **GR00T 정책** 추론 엔진 (`robotis/groot-zenoh`) |
| `ai_worker` | 로봇 제어 (실물/mock) |

정책 종류에 따라 **다른 엔진**이 뜬다 — LeRobot은 `lerobot_server`, GR00T는 `groot_server`.

---

## 1. 설치

[공식 install 스크립트](https://github.com/ROBOTIS-GIT/cyclo_intelligence):
```bash
curl -fsSL https://raw.githubusercontent.com/ROBOTIS-GIT/cyclo_intelligence/main/install.sh | bash
```
- 호스트명이 `ffw` 로 시작하는 **로봇 PC**: `/mnt/ssd/cyclo_intelligence` 에 설치 + `~/cyclo_intelligence` bind-mount
- 그 외: `~/cyclo_intelligence`

컨테이너 확인:
```bash
cd ~/cyclo_intelligence
docker ps        # cyclo_intelligence, lerobot_server 가 Up (healthy)
```

---

## 2. 모델을 어디에 두나 — **가장 중요한 것**

정책은 **`/workspace/model/<backend>/<이름>/`** 에 둔다. 호스트 경로로는:

```
~/cyclo_intelligence/docker/workspace/model/lerobot/<이름>/    ← LeRobot 정책
~/cyclo_intelligence/docker/workspace/model/groot/<이름>/      ← GR00T 정책
```

> ⚠️ **`~/.cache/huggingface/...` 가 아니다.** UI가 읽는 드롭박스는 `/workspace/model/{lerobot,groot}/` 다.
> ⚠️ **학습 컨테이너의 `/workspace` 와 헷갈리지 말 것.** `docker run ... gr00t`(학습용)의 `/workspace` 와
> cyclo_intelligence의 `/workspace` 는 **다른 컨테이너**다. cyclo 쪽에 둬야 웹에 보인다
> → 호스트의 `~/cyclo_intelligence/docker/workspace/model/` 에 두는 게 제일 확실.

### 추론에 필요한 파일만 (checkpoint 등은 뺀다)

**GR00T** — 7개면 된다:
```
config.json
model-00001-of-00003.safetensors
model-00002-of-00003.safetensors
model-00003-of-00003.safetensors
model.safetensors.index.json
experiment_cfg/          ← modality (19-dim/카메라1개) 정보
processor_config.json    (또는 processor/ 폴더)
```
**LeRobot (0.5.2)** — 정규화 파일이 핵심:
```
config.json
model.safetensors
policy_preprocessor.json
policy_preprocessor_step_*_normalizer_processor.safetensors     ← 입력 정규화 (필수!)
policy_postprocessor.json
policy_postprocessor_step_*_unnormalizer_processor.safetensors  ← 출력 역정규화 (필수!)
train_config.json
```
> ❌ **빼는 것**: `checkpoint-*/`(각 수GB 중복), `optimizer.pt`, `scheduler.pt`, `rng_state.pth`,
> `trainer_state.json`, `training_args.bin`, `wandb_config.json` — 전부 학습 재개용이라 추론엔 불필요.
>
> ⚠️ **LeRobot은 반드시 0.5.2로 학습한 것.** 옛 0.3.3 모델(preprocessor/postprocessor 파일 없음)은
> 로드돼도 정규화가 안 돼 로봇이 이상하게 움직인다 → 0.5.2로 재학습해야 한다.

---

## 3. HF에서 모델 받아 배치

**cyclo_intelligence 캐시가 호스트에 마운트**돼 있으므로 호스트에서 직접 받는 게 깔끔하다.

### GR00T 예시 (HF repo에 checkpoint-* 로 저장된 경우)

최종 스텝만 골라서 받는다:
```bash
# 어떤 체크포인트가 있나
python3 -c "from huggingface_hub import HfApi; import re; print(sorted({int(m.group(1)) for f in HfApi().list_repo_files('JSHNSL/groot_ffw_ltable') if (m:=re.match(r'checkpoint-(\d+)/',f))}))"
```
```bash
# 최종(예: 20000)만 받기
hf download JSHNSL/groot_ffw_ltable --include "checkpoint-20000/*" --local-dir /tmp/g
```
```bash
# 필요한 것만 배치 (한 줄 — 여러 줄로 나누면 공백이 깨진다)
DST=~/cyclo_intelligence/docker/workspace/model/groot/groot_ffw_ltable_20k
mkdir -p "$DST"
cp -a /tmp/g/checkpoint-20000/config.json /tmp/g/checkpoint-20000/model-00001-of-00003.safetensors /tmp/g/checkpoint-20000/model-00002-of-00003.safetensors /tmp/g/checkpoint-20000/model-00003-of-00003.safetensors /tmp/g/checkpoint-20000/model.safetensors.index.json /tmp/g/checkpoint-20000/experiment_cfg /tmp/g/checkpoint-20000/processor_config.json "$DST"/
```
```bash
# ⭐ 모델 3개가 GB 단위로 들어갔는지 반드시 확인
ls -la "$DST"
```

### LeRobot 예시 (repo 최상위에 파일이 있는 경우)

```bash
DST=~/cyclo_intelligence/docker/workspace/model/lerobot/diffusion_ffw
hf download JSHNSL/diffusion_ffw_ltable --local-dir "$DST"
```

> 컨테이너가 root로 만든 폴더는 root 소유가 된다. 호스트에서 만지려면 `sudo`, 또는
> `sudo chown -R $USER:$USER ~/cyclo_intelligence/docker/workspace/model`.

---

## 4. 웹 UI에서 실행

브라우저로 cyclo_intelligence 접속 → **Inference**:
1. 모델 타입 — **ACT / VQ-BeT / Diffusion** (LeRobot) 또는 **N1.7** (GR00T)
2. User — 폴더 구조상 owner (예: `JSHNSL`) 또는 직접 배치한 이름
3. Policy — 방금 배치한 폴더 이름
4. **Load** → 로딩되면 **Inference**로 넘어감

성공 로그 (엔진 컨테이너):
```bash
docker logs -f groot_server 2>&1 | grep -v "Service call timed out"   # GR00T
docker logs -f lerobot_server                                          # LeRobot
```
GR00T가 뜨면:
```
Loading GR00T policy from: /workspace/model/groot/groot_ffw_ltable_20k
Policy info: {'video': ['cam_left_head'], 'state': ['arm_left','arm_right','head','lift'], ...}
Action chunk: T=16, D=19        ← 추론이 실제로 돌고 있음
```

---

## 5. 자주 걸리는 것 (실전)

| 증상 | 원인 / 해결 |
|------|------------|
| **웹 UI Loading 무한** (GR00T) | `groot_server` 자동 기동 실패 → `docker start groot_server` 후 UI에서 다시 Load |
| **웹에 모델이 안 보임** | `/workspace/model/<backend>/` 가 아닌 곳에 뒀거나, **학습 컨테이너**`/workspace` 에 넣음 → cyclo 쪽 `~/cyclo_intelligence/docker/workspace/model/` 에 배치 |
| **Diffusion/VQ-BeT 로드는 되는데 로봇 안 움직임** | 큐 기반 정책 엔진 버그 → [`cyclo-intelligence-patches`](https://huggingface.co/JSHNSL/cyclo-intelligence-patches) 한 줄 적용 (`prediction.py` 패치 + `diffusers` 설치) |
| **`No module named 'diffusers'`** (Diffusion) | `docker exec lerobot_server sh -c 'VIRTUAL_ENV=/lerobot/.venv uv pip install diffusers'` (이 컨테이너엔 pip 없음, uv 사용) |
| **VQ-BeT 드롭다운에 없음** | UI에 항목 추가 + root로 재빌드 → patches repo 참고 |
| **ACT는 되는데 접근만 하고 grasp 약함** | 정책 성능/시각 조건 문제 (단일 cam_head). 배포 버그 아님 |
| **옛 ACT(0.3.3) 로드했는데 이상** | preprocessor/postprocessor 파일 없음 → **0.5.2로 재학습** |
| **`Timeout waiting for sensors: camera:cam_right_head`** | 로봇 config가 카메라 4개 기대. 정책이 1개만 쓰면 **경고일 뿐 추론은 진행됨** |
| **카메라 회색 / 로봇 mock** | **실물 로봇·카메라가 없는 PC**라서. 실제 동작은 로봇이 연결된 PC에서만 |
| 모델 파일 root 소유 | `sudo chown -R $USER:$USER ~/cyclo_intelligence/docker/workspace/model` |

---

## 6. 정책별 요약

| 정책 | 엔진 | 배치 위치 | 특이사항 |
|------|------|-----------|----------|
| **ACT** | lerobot_server | `model/lerobot/` | 바로 됨 (0.5.2) |
| **Diffusion** | lerobot_server | `model/lerobot/` | 엔진 패치 + `diffusers` 필요 |
| **VQ-BeT** | lerobot_server | `model/lerobot/` | 엔진 패치 + UI 항목 추가 필요 |
| **GR00T N1.7** | groot_server | `model/groot/` | `groot_server` 수동 기동 필요할 수 있음 |

> Diffusion·VQ-BeT 관련 패치는 [`JSHNSL/cyclo-intelligence-patches`](https://huggingface.co/JSHNSL/cyclo-intelligence-patches) 에 한 줄 적용 스크립트로 있다.

---

## ⚠️ 실물 로봇이 없는 PC에서는

로드·추론(Action chunk 생성)까지는 되지만, **실제 로봇 움직임은 안 보인다** — 카메라는 회색(mock),
관절도 mock. 이 PC에서 확인 가능한 것은:
- ✅ 모델이 **로드되는가**
- ✅ modality를 **정확히 인식하는가** (`Policy info`)
-**추론이 도는가** (`Action chunk`)

**실제 grasp/이동**은 ZED+RealSense가 달린 **실물 FFW_SG2 로봇 PC**에서만 의미가 있다.