Quick Start
This section covers environment and weight preparation for Wall-OSS-0.5. All commands are executed by default in the root directory of the wall-x/ repository, and all /path/to/ paths must be replaced with actual local paths.
This section covers environment and weight preparation for Wall-OSS-0.5. All commands are executed by default in the root directory of the wall-x/ repository, and all /path/to/ paths must be replaced with actual local paths.
Official deployment tutorial:
Wall-OSS-0.5 official deployment tutorial
Environment setup
# 1. Create and activate the environment
conda create --name wallx python=3.10 -y
conda activate wallx# 2. Install the base dependencies
pip install -r requirements.txt
pip install "dmuon @ git+https://github.com/X-Square-Robot/dmuon.git"# 3. Install LeRobot
git clone https://github.com/huggingface/lerobot.git
cd lerobot
git checkout v0.4.4
pip install --no-deps -e .
cd ../Install Wall-X
export CUDA_HOME=/usr/local/cuda-12.8 # Change to the root directory where your nvcc is located; CUDA 12.8 is recommended to match the torch version
export PATH="$CUDA_HOME/bin:PATH"
which nvcc && nvcc --version
MAX_JOBS=8 pip install --no-build-isolation -e .# 5. Install flash-attn
export FLASH_ATTN_CUDA_ARCHS=$(python -c 'import torch; print(f"{torch.cuda.get_device_capability()[0]}{torch.cuda.get_device_capability()[1]}")')
MAX_JOBS=4 pip install flash-attn==2.8.3 --no-build-isolationflash-attn is not in requirements.txt, but it is a hard dependency (joint.py unconditionally imports is_flash_attn_greater_or_equal_2_10)
Download Wall-OSS-0.5 weights
Download from Hugging Face
Network issues
If there are network issues when accessing Hugging Face, you can use the following:
export HF_ENDPOINT=https://hf-mirror.com
hf download <repo_id> --local-dir <your-path>Wall-OSS-0.5 is built on Qwen2.5-VL-3B. Fine-tuning and inference require two sets of files: the Wall-OSS model weights and the Qwen weights.
Download the ManipArena Dataset (If Needed)
You need to apply for dataset access permissions on the webpage and provide an HF read token
When --local-dir points to an existing directory, failure to connect to the remote Hub will cause it to return the directory as is, print a green checkmark, and exit with code 0, making it look completely successful even though no files were actually downloaded.
In addition, repositories with more than 1,000 files will inevitably encounter pagination issues: the mirror returns an absolute huggingface.co address in the Link: next header, resulting in Errno 101 errors starting from the second page, so you have to enumerate files manually and download them one by one using hf_hub_download
Script:
"""Download every file in a Hub repo without snapshot_download pagination.
hf-mirror's tree API returns absolute huggingface.co Link: next headers after
the first 1000 files. dataset_info().siblings is a complete path list and
hf_hub_download honors HF_ENDPOINT.
Usage:
HF_ENDPOINT=https://hf-mirror.com HF_HUB_DISABLE_XET=1 HF_TOKEN=... \
python workspace/download_hf_siblings.py \
--repo-id ManipArena/maniparena-dataset \
--repo-type dataset \
--local-dir /path/to/dir
"""
from __future__ import annotations
import argparse
import os
import sys
import time
from concurrent.futures import ThreadPoolExecutor, as_completed
from pathlib import Path
from huggingface_hub import dataset_info, hf_hub_download, model_info
def list_files(repo_id: str, repo_type: str) -> list[str]:
info_fn = dataset_info if repo_type == "dataset" else model_info
info = info_fn(repo_id)
if not info.siblings:
raise RuntimeError(f"{repo_id}: empty siblings list")
return [s.rfilename for s in info.siblings]
def already_have(local_dir: Path, filename: str) -> bool:
path = local_dir / filename
return path.is_file() and path.stat().st_size > 0
def fetch(repo_id: str, repo_type: str, filename: str, local_dir: str, retries: int) -> str:
last: Exception | None = None
for attempt in range(retries):
try:
return hf_hub_download(
repo_id,
filename,
repo_type=repo_type,
local_dir=local_dir,
)
except Exception as exc: # noqa: BLE001
last = exc
time.sleep(min(2**attempt, 16))
raise RuntimeError(f"{filename}: {type(last).__name__} {last}") from last
def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument("--repo-id", required=True)
parser.add_argument("--repo-type", default="dataset", choices=["dataset", "model"])
parser.add_argument("--local-dir", required=True)
parser.add_argument("--workers", type=int, default=8)
parser.add_argument("--retries", type=int, default=4)
args = parser.parse_args()
local_dir = Path(args.local_dir)
local_dir.mkdir(parents=True, exist_ok=True)
files = list_files(args.repo_id, args.repo_type)
pending = [f for f in files if not already_have(local_dir, f)]
print(
f"{args.repo_id}: {len(files)} files, {len(files) - len(pending)} already present, "
f"{len(pending)} to fetch",
flush=True,
)
if not pending:
print(f"OK {args.repo_id} -> {local_dir}", flush=True)
return
done = 0
errors: list[str] = []
t0 = time.time()
with ThreadPoolExecutor(max_workers=args.workers) as pool:
futures = {
pool.submit(fetch, args.repo_id, args.repo_type, f, str(local_dir), args.retries): f
for f in pending
}
for future in as_completed(futures):
try:
future.result()
except Exception as exc: # noqa: BLE001
errors.append(str(exc))
done += 1
if done % 100 == 0 or done == len(pending):
dt = time.time() - t0
print(
f" {done}/{len(pending)} errors={len(errors)} {dt:.0f}s",
flush=True,
)
if errors:
print(f"FAILED {len(errors)} files, first: {errors[0]}", flush=True)
sys.exit(1)
print(f"OK {args.repo_id} -> {local_dir}", flush=True)
if __name__ == "__main__":
main()Model page:
Using the command line is recommended:
huggingface-cli download X-Square-Robot/wall-oss-0.5 --local-dir /path/to/wall-oss-0.5You can also use Python
from huggingface_hub import snapshot_download
snapshot_download(
"X-Square-Robot/wall-oss-0.5",
local_dir="/path/to/wall-oss-0.5",
)After downloading, verify at least the following:
| Core files | Function |
|---|---|
| config.json | Model architecture configuration, corresponding to model.config_path in the training YAML |
| model.safetensors | Pretrained weights, corresponding to checkpoint.resume_from |
| Tokenizer / processor files | Essential files for model inference and data preprocessing |
Download Qwen2.5-VL-3B-Instruct
Wall-OSS-0.5 is built upon Qwen2.5-VL-3B. Training and inference also require processor files:
huggingface-cli download Qwen/Qwen2.5-VL-3B-Instruct --local-dir /path/to/Qwen2.5-VL-3B-InstructPoint model.processor_path and model.pretrained_path to this directory in the training configuration.
Quick check
-
Python environment can be activated;
-
Wall-X, dmuon, and LeRobot are installed successfully;
-
config.json and model.safetensors are complete;
-
Qwen2.5-VL-3B-Instruct processor directory is complete;
-
GPU, CUDA, and PyTorch are available;
-
All configuration paths have been replaced.
Core resources
| Resource | Purpose |
|---|---|
| workspace/example/libero.yml | LIBERO single-arm simulation fine-tuning |
| workspace/example/maniparena_example.yml | Real-robot dual-arm fine-tuning and deployment |
| scripts/compute_norm_stats.py | Generate dataset normalization statistics |
| scripts/run_libero.sh | LIBERO simulation batch evaluation |
| scripts/run_serving.sh | Start real-robot WebSocket inference service |
| scripts/draw_openloop_plot.py | Open-loop inference visualization |
| scripts/merge_sharded_weights.py | Merge FSDP sharded weights |