עמוד המדריך של AY-Robots לאימון GR00T N1.7 על זרוע SO-100, המציג את רמת ה-GPU הנדרשת, פורמט סט הנתונים וברירות המחדל של המאמן
GR00T N1.7SO-100כוונון עדיןLeRobotVLA

איך לאמן את GR00T N1.7 על סט נתונים משלך של SO-100

AY-Robots ResearchAugust 23, 202628 דקות קריאה

מדריך בדוק לכוונון עדין של NVIDIA GR00T N1.7 על סט נתונים של LeRobot מסוג SO-100: דגלים אמיתיים, modality.json, דרישת v2.1, כמה עולה הרצה, והמלכודות.

NVIDIA מספקת דוגמת כוונון עדין בדיוק עבור הזרוע שכנראה בבעלותך. בתוך מאגר Isaac-GR00T קיימת תיקייה בשם demo_data/cube_to_bowl_5: חמישה פרקים, 4,148 פריימים ב-30 פריימים לשנייה, כתובים כבר בפורמט LeRobot v2.1, עם קונפיגורציית מודליות תואמת תחת examples/SO100/. ה-meta/info.json שלה מדווח על robot_type: so101_follower, אשר ב-LeRobot היא אותה מחלקת קונפיגורציה כמו so100_follower. זה שימושי באמת, כי זה אומר שנתיב הייחוס עבור GR00T N1.7 על זרוע תחביב בעלת שש דרגות חופש מתוחזק על ידי האנשים שכתבו את המודל. זו אינה הדגמה הומנואידית מוקטנת, זו אותה זרוע.

החדשות הרעות הן המרחק בין I recorded 60 episodes לבין the arm does the task. ישנם כששה מקומות שבהם צינור עבודה זה נכשל בשקט במקום ברעש, וארבעה מהם נמצאים בקבצים שרוב האנשים לעולם אינם פותחים: meta/modality.json, קונפיגורציית נתוני הפייתון, meta/relative_stats.json, ומחרוזת הגרסה של מערך הנתונים עצמו. מדריך זה מציג את המסלול הידני מקצה לקצה עם הפקודות האמיתיות, ולאחר מכן מראה את אותה עבודה כטופס ב-AY-Robots. כל מה שלמטה נבדק מול ענף ה-main של Isaac-GR00T נכון ל-20 באוגוסט 2026 (קו הגרסה n1.7-release) ו-lerobot 0.6.1, שפורסם ל-PyPI ב-3 באוגוסט 2026. ה-upstream מתפתח במהירות, ובמקרה שדגל שונה, מאמר זה מציין זאת.

מה שצריך לדעת לפני שמתחילים

  • כוונון עדין של GR00T N1.7 דורש 40 GB או יותר של VRAM. NVIDIA ממליצה על צמתי H100 או L40. כרטיס RTX 4090 עם 24 GB לא יבצע עבודה זו, אם כי הוא יאמן את SmolVLA ו-ACT.
  • מערך הנתונים חייב להיות LeRobot v2 (v2.0 או v2.1) בתוספת meta/modality.json ספציפי ל-GR00T. מערך נתונים של LeRobot v3.0 אינו נטען ויש להמירו לגרסה נמוכה יותר.
  • נקודת הכניסה היא gr00t/experiment/launch_finetune.py, כלי CLI מסוג tyro. אין לו דגל --seed, ולכן הרצות אינן ניתנות לשחזור ביט-אחר-ביט.
  • עבור זרוע מותאמת אישית, תגית ה-embodiment היא NEW_EMBODIMENT, ותגית זו הופכת את --modality-config-path לחובה.
  • המתכון המצורף של SO-100 חוזה מפרקי זרוע כדלתות יחסיות (RELATIVE deltas) ואת התופסן כמטרה מוחלטת (ABSOLUTE target). היפוך זיווג זה הוא כשל שקט, לא שגיאה.
  • ב-AY-Robots אותה עבודה היא טופס: 20000 צעדים, אצווה 32, קצב למידה 1e-4, בערך 4 עד 12 דולר בשכבת A100 80 GB או H100.

מהו GR00T N1.7 בפועל

GR00T N1.7 הוא מודל ראייה-שפה-פעולה עם מבנה דו-מערכתי כפי שתואר במאמר המקורי של GR00T N1: מודול ראייה-שפה שקורא את המצלמות ואת ההוראה, וטרנספורמר דיפוזיה שהופך זאת למקטע של פקודות מנוע רציפות. N1.7 החליף את החצי הראשון. עמוד השדרה של Eagle מ-N1.6 הוסר, והוחלף ב-nvidia/Cosmos-Reason2-2B על ארכיטקטורת Qwen3-VL, והמודל אומן מראש על כ-20,000 שעות של וידאו אנושי אגוצנטרי בנוסף לנתוני הרובוט. התיאור של NVIDIA עצמה מציין את הנתון ב-20,854 שעות ומדווח כי מעבר מ-1k ל-20k שעות יותר ממכפיל את השלמת המשימות הממוצעת.

החצי השני השתנה גם הוא, בדרכים שחשובות להרצה שלך. ראש הפעולה ירד מ-32 שכבות דיפוזיה ל-16, מקטע הפעולה גדל מ-16 צעדים ל-40, ורוחב המצב והפעולה המקסימלי עבר מ-29 ל-132. שלושת המספרים הללו מגיעים מיומן השינויים בקובץ ה-README של המאגר; פוסט ההשקה של NVIDIA עצמה עדיין מתאר את מערכת 1 כ-DiT בעל 32 שכבות, כך שבמקום שבו השניים חלוקים, סמוך על המאגר שאתה עומד לשכפל. פעולות מבוטאות כברירת מחדל במרחב קצה-אפקטור יחסי, דלתות מהתנוחה הנוכחית ולא יעדים מוחלטים, וזה מה שמאפשר להעביר ידע קודם של מניפולציה שנלמד מוידאו אנושי לבקרת רובוטים בכלל. הראש עצמו הוא טרנספורמר דיפוזיה של התאמת זרימה, מאותה משפחה כמו Pi0.5 אך עם עמוד שדרה שונה לפניו. אם אתה עדיין בדור הקודם, N1.7 מול N1.5 מכסה האם השדרוג מצדיק את בניית ה-pipeline מחדש.

PropertyValueWhere it comes from
פרמטרים3,000,000,000כרטיס מודל של Hugging Face
עמוד שדרה ראייה-שפהnvidia/Cosmos-Reason2-2B (Qwen3-VL), gated on Hugging Facerepo README
ראש פעולהFlow-matching diffusion transformer, 16 layers (N1.6 had 32)repo README
אופק פעולה חזוי40 steps for the base checkpoint (N1.6 had 16)getting_started/policy.md and repo README
רוחב מצב ופעולה מקסימלי132 (N1.6 had 29)repo README
רישיון קודApache 2.0Isaac-GR00T repository
רישיון משקליםNVIDIA Open Model License Agreementכרטיס מודל
זמן אחזור, H100 80 GB, PyTorch eager, 4 שלבי הסרת רעש, מצלמה אחת85.8 ms end to end, 11.7 Hzטבלת תזמון של כרטיס המודל
אותה חומרה, TensorRT pipeline מלא27.9 ms end to end, 35.9 Hzטבלת תזמון של כרטיס המודל
זמן אחזור ש-AY-Robots מצטטת עבור GR00T N1.7 המוגש שלה152 ms per action stepAY-Robots policy catalog

שלוש השורות האחרונות מסבירות את רוב האכזבה שאנשים מדווחים עליה. הכותרת של 27.9 אלפיות השנייה היא מנוע TensorRT על H100 עם מצלמה אחת וארבעה שלבי הסרת רעש. PyTorch רגיל על אותו כרטיס הוא 85.8 אלפיות השנייה, וכרטיס המודל מציין את הפער כ-3.08x. אף אחד מהמספרים אינו כולל שכבת שירות, מצלמה שנייה או קפיצת רשת. ה-152 אלפיות השנייה לכל שלב פעולה ש-AY-Robots מצטטת עבור GR00T N1.7 המוגש שלה הוא הנתון עם שירות בלולאה, ונסיעה הלוך ושוב באינטרנט ציבורי יושבת מעל זה. עוד על כך בסוף. עבור המספרים ליד מודלים אחרים, GR00T N1.7 מול Pi0.5 ו-GR00T N1.7 מול SmolVLA מציגים אותם זה לצד זה.

עמוד המודל של AY-Robots עבור GR00T N1.7 המציג את ספירת הפרמטרים, רמת ה-GPU, זמן השהיית ההסקה ואת החוזקות והמגבלות המוצהרות של המודל.
העמוד /policies/groot-n1-7 מציג את אותו פס מפרטים שהייתם מרכיבים ידנית מכרטיס המודל ומקובץ ה-README של המאגר.

מה שההרצה דורשת לפני שתקלידו משהו

דרישהאימון עדין (Fine-tuning)הסקה (Inference)
VRAM, הנחיות NVIDIA40 GB או יותר, מומלץ H100 או L4016 GB או יותר, RTX 4090 יעבוד
Python ו-CUDA על dGPU3.12 and CUDA 12.83.12 and CUDA 12.8
קצה עורפי לווידאוtorchcodec 0.8.0, FFmpeg 4 עד 7 בלבדכנ"ל
פורמט מערך הנתוניםLeRobot v2 plus meta/modality.jsonלא רלוונטי
גישה ל-Hugging Faceמאושר עבור nvidia/Cosmos-Reason2-2Bכנ"ל
כלים נוספיםgit-lfs and uvuv
רמת GPU של AY-Robots עבור מאמן groot1.7A100 80 GB or H100 80 GBpod מסופק אוטומטית
הליבה המגודרת תעצור אתכם בהרצה הראשונה

כל נקודת שמירה של GR00T, כולל הבסיס nvidia/GR00T-N1.7-3B, טוענת את nvidia/Cosmos-Reason2-2B בשימוש הראשון, ומאגר זה מגודר. קובץ ה-README מציין את הכישלון במדויק: טעינת המודל נכשלת עם GatedRepoError / 401 Client Error. מה שהוא לא מציין זה מתי זה קורה, וזה קורה לאחר ששכרתם את הכרטיס וההרצה החלה. בקשו גישה בעמוד המודל, ואז הריצו uv run huggingface-cli login או ייצאו את HF_TOKEN לפני שאתם שוכרים משהו.

שלב 0: הפרקים עצמם

כל מה שלמטה מניח שכבר הקלטתם פרקים. אם לא, זהו הצעד הראשון האמיתי והוא זה שמחליט עד כמה התוצאה יכולה להיות טובה, מכיוון ש-למידת חיקוי אינה יכולה לשחזר מידע שאינו נמצא בנתונים. כיילו את שתי הזרועות תחילה, ולאחר מכן הניעו את העוקב עם זרוע מובילה בזמן ש-lerobot-record כותב את קבצי ה-parquet ואת זרמי המצלמה. אם כיול אינו מדויק, ערכי המפרקים במערך הנתונים שלכם מתארים רובוט שונה במקצת מזה שיבצע מאוחר יותר את המדיניות, ושום כמות אימונים לא תתקן זאת.

bash
lerobot-record \
    --robot.type=so100_follower \
    --robot.port=/dev/ttyACM0 \
    --robot.id=my_follower_arm \
    --robot.cameras="{ front: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30}, wrist: {type: opencv, index_or_path: 2, width: 640, height: 480, fps: 30}}" \
    --teleop.type=so100_leader \
    --teleop.port=/dev/ttyACM1 \
    --teleop.id=my_leader_arm \
    --dataset.repo_id=${HF_USER}/cube-into-bowl \
    --dataset.num_episodes=60 \
    --dataset.single_task="put the cube in the yellow bowl" \
    --display_data=true
lerobot-record על LeRobot עדכני. אורך פרק ברירת המחדל הוא 60 שניות וזמן האיפוס הוא 60 שניות. so100_follower ו-so101_follower רשומים שניהם מול אותה מחלקת תצורה של LeRobot, ולכן הדוגמה של Isaac-GR00T SO100 משתמשת בשמות so101; שניהם עובדים על SO-100. שמות המצלמות שתבחרו כאן (front, wrist) הם השמות שצריכים להופיע שוב ב-modality.json.

העצה של LeRobot היא להקליט לפחות 50 פרקים עם כ-10 פרקים לכל מיקום אובייקט, לשמור את המצלמות קבועות, ולשמור על התנהגות אחידה של אחיזה. הוסיפו וריאציה מאוחר יותר, לא בהתחלה. כלל האצבע שכדאי לזכור: אם לא הייתם יכולים לבצע את המשימה בעצמכם מתמונות המצלמה בלבד, גם ה-מדיניות לא יכולה. עבור ההגדרה הספציפית לזרוע, תחילת עבודה עם SO-100 ו-דף ה-LeRobot של SO-100 מכסים יציאות, כיול ואינדקסי מצלמה. ב-AY-Robots ניתן גם לבצע זאת דרך האינטרנט מהדפדפן באמצעות טלאופרציה ולהקליט ישירות מהסשן.

שלב 1: מערך הנתונים חייב להיות LeRobot v2.1

זוהי המכשלה הנפוצה ביותר. ה-LeRobot הנוכחי CODEBASE_VERSION ב-main הוא v3.0, כך שכל מה שתקליטו היום עם שרשרת כלים עדכנית יצא כ-v3.0. הטוען של GR00T מצפה ל-v2. המאגר מפרט מדוע: מערכי נתונים רבים במעלה הזרם כגון DROID, LIBERO ו-Bridge מתפרסמים ב-v2, ותמיכה מובנית בשניהם מתוכננת אך עדיין לא נשלחה. לכן ההמרה היא באחריותכם, והיא רצה בסביבה וירטואלית משלה מסיבה מוגדרת: scripts/lerobot_conversion נושא פרויקט פייתון משלו הדורש Python 3.10 או 3.11 ומקבע את lerobot לקומיט גיט אחד, בעוד ש-Isaac-GR00T עצמו דורש Python 3.12. התקינו את הממיר משורש המאגר ותקבלו את חבילת ה-gr00t במקום זאת, וזו הטעות שה-README שלו מזהיר מפניה. אם אתם חדשים לפורמט, ערך המילון מערך נתונים של LeRobot מסביר מה באמת נמצא בתוכו.

bash
# from the Isaac-GR00T repo root
cd scripts/lerobot_conversion
uv venv
source .venv/bin/activate
uv pip install -e . --verbose

# pulls the dataset from the Hub and writes a v2.1 copy into the default cache
python convert_v3_to_v2.py --repo-id <your-hf-user>/<your-dataset>

# or, back in the repo root, keep it next to the SO-100 example
uv run --project scripts/lerobot_conversion \
  python scripts/lerobot_conversion/convert_v3_to_v2.py \
  --repo-id <your-hf-user>/<your-dataset> \
  --root examples/SO100/my_dataset_lerobot
הממיר מקבל את --repo-id, --root אופציונלי, ו- --force-conversion, אשר מוחק כל תמונת מצב מקומית קיימת ומוריד אותה מחדש. הוא כותב codebase_version: v2.1 לתוך meta/info.json.
ההמרה דורסת במקום

אם מערך הנתונים v3.0 כבר קיים מקומית, הסקריפט בונה את פריסת v2.1 לצידו ולאחר מכן מבצע החלפה: המקור מועבר לתיקיית אח עם גרסה מצורפת, <name>_v3.0, והעותק המומר תופס את הנתיב המקורי. (ה-docstring של הסקריפט עצמו קורא לתיקייה זו _v30; הקוד מצרף את מחרוזת הגרסה, כך שמה שתקבלו בפועל הוא _v3.0.) הפתעה שנייה: הפלט תמיד נוחת תחת <root>/<repo-id>, כך ש---root examples/SO100/my_dataset_lerobot ייתן לכם examples/SO100/my_dataset_lerobot/<your-hf-user>/<your-dataset>, והנתיב הארוך יותר הזה הוא מה ש---dataset-path ירצה מאוחר יותר. כאשר עבודת אימון דוחה את מערך הנתונים שלכם מסיבות גרסה, הדף 'מערך נתונים נדחה כ-v3' מפרט את הסימפטומים המדויקים.

המבנה ש-GR00T רוצה לאחר ההמרה הוא פריסת v2 הקלאסית: meta/info.json, meta/episodes.jsonl, meta/tasks.jsonl, קובצי parquet תחת data/chunk-000/, קובצי MP4 תחת videos/chunk-000/observation.images./, וקובץ נוסף אחד שאין ל-LeRobot הסטנדרטי. הקובץ הנוסף הזה הוא המקום שבו נמצאות רוב הכשלים הנותרים.

שלב 2: modality.json, ששת המספרים שמחליטים הכל

במערך נתונים של LeRobot, מצב הרובוט והפעולה מאוחסנים כמערכי float32 שטוחים. עבור SO-100, לשניהם יש צורה [6]: חמישה מפרקי זרוע ותופסן. מערך הנתונים לדוגמה קורא להם shoulder_pan.pos, shoulder_lift.pos, elbow_flex.pos, wrist_flex.pos, wrist_roll.pos, gripper.pos, אך שמות אלה נמצאים ב-info.json ושום דבר בקובץ ה-parquet לא מציין איזה אינדקס הוא איזה. meta/modality.json מספק את המיפוי הזה, ו-GR00T לא יתאמן בלעדיו. הנה הקובץ שהמאגר מספק עבור ה-SO-100, כלשונו.

json
{
  "state": {
    "single_arm": {
      "start": 0,
      "end": 5
    },
    "gripper": {
      "start": 5,
      "end": 6
    }
  },
  "action": {
    "single_arm": {
      "start": 0,
      "end": 5
    },
    "gripper": {
      "start": 5,
      "end": 6
    }
  },
  "video": {
    "front": {
      "original_key": "observation.images.front"
    },
    "wrist": {
      "original_key": "observation.images.wrist"
    }
  },
  "annotation": {
    "human.task_description": {
      "original_key": "task_index"
    }
  }
}
examples/SO100/modality.json. האינדקסים מבוססי אפס ועוקבים אחר חיתוך פייתון, כך ש-single_arm הוא [0:5] והתופסן הוא [5:6].

העתיקו אותו לסט הנתונים המומר שלכם ב-meta/modality.json ושנו את שמות מפתחות הווידאו לשמות המצלמות שלכם בפועל. אם הקלטתם עם מצלמת תקרה בודדת בשם top, אז original_key הוא observation.images.top והשם הידידותי הוא מה שתצורת הנתונים שלכם תתייחס אליו. השניים חייבים להיות תואמים, ואף אחד מהם לא בודק את השני עבורכם. הערת השפה גרועה יותר, מכיוון שאותו מפתח חייב להופיע בשלושה מקומות.

שכבהקובץצורת SO-100 המשמשת במאגר
עמודת Parquetdata/chunk-*/episode_*.parquetannotation.human.task_description
מפתח modality.jsonmeta/modality.json, תחת "annotation", ללא הקידומת annotation.human.task_description
modality_keys בתצורת הנתוניםקובץ so100_config.py שלכםannotation.human.task_description
מדוע מפתח השפה מבלבל אנשים

המקטעים שאחרי annotation. נבחרים על ידי מי שיצר את סט הנתונים. נתוני הדמו של SO-100 משתמשים ב-annotation.human.task_description; LIBERO ו-SimplerEnv משתמשים ב-annotation.human.action.task_description. שניהם תקינים. אם העתקתם תצורה מדוגמת LIBERO והפניתם אותה להקלטת SO-100 משלכם, ערוץ השפה מתורגם לכלום והמודל מתאמן על הוראה ריקה. ההפסד עדיין יורד. המדיניות עדיין עושה משהו. היא פשוט מתעלמת ממה שאמרתם לה לעשות.

שלב 3: תצורת הנתונים, זרוע יחסית ותופסן מוחלט

קונפיגורציית המודאליות היא קובץ Python ולא JSON, מכיוון שהיא גם קובעת כיצד כל קבוצת פעולה מיוצגת. זהו החלק בזרימת העבודה של N1.7 שלא היה קיים באותה צורה ב-N1.5, והחלק ששווה לקרוא פעמיים. קונפיגורציית SO-100 המסופקת מנבאת את חמשת מפרקי הזרוע כ-RELATIVE דלתות מהמצב הנוכחי ואת התפסן כ-ABSOLUTE מיקום יעד, מכיוון שאות בינארי של פתוח-או-סגור מתנהג טוב יותר כיעד מאשר כדלתא.

python
from gr00t.configs.data.embodiment_configs import register_modality_config
from gr00t.data.embodiment_tags import EmbodimentTag
from gr00t.data.types import (
    ActionConfig, ActionFormat, ActionRepresentation, ActionType, ModalityConfig,
)

so100_config = {
    "video": ModalityConfig(
        delta_indices=[0],                       # current frame only
        modality_keys=["front", "wrist"],        # must match modality.json
    ),
    "state": ModalityConfig(
        delta_indices=[0],
        modality_keys=["single_arm", "gripper"],
    ),
    "action": ModalityConfig(
        delta_indices=list(range(0, 16)),        # predict 16 future steps
        modality_keys=["single_arm", "gripper"],
        action_configs=[
            ActionConfig(rep=ActionRepresentation.RELATIVE,   # arm joints
                         type=ActionType.NON_EEF,
                         format=ActionFormat.DEFAULT),
            ActionConfig(rep=ActionRepresentation.ABSOLUTE,   # gripper
                         type=ActionType.NON_EEF,
                         format=ActionFormat.DEFAULT),
        ],
    ),
    "language": ModalityConfig(
        delta_indices=[0],
        modality_keys=["annotation.human.task_description"],
    ),
}

register_modality_config(so100_config, embodiment_tag=EmbodimentTag.NEW_EMBODIMENT)
examples/SO100/so100_config.py, קוצץ לעיקר. NON_EEF פירושו מרחב מפרקים; EEF יצפה לווקטור תשעה ממדים של x, y, z בתוספת סיבוב 6D.

שני פרטים כאן יעלו לכם יום אם לא תדעו אותם. ראשית, action_configs הוא פוזיציונלי: התיעוד דורש את אותו אורך ואותו סדר כמו modality_keys, והם מפורשים לגבי ההשלכה של טעות, שהיא יישום שגוי של הייצוג בשקט. התפסן שלכם מאומן כדלתא והזרוע שלכם כיעד מוחלט, ואין הודעת שגיאה. שנית, register_modality_config מאשר שאין תגית כזו רשומה כבר, כך שקונפיגורציית NEW_EMBODIMENT שנייה באותו תהליך Python תיכשל עם Embodiment tag ... already registered. אינכם יכולים לייבא שתי קונפיגורציות כאלה לסקריפט אחד. כלל שלישי נאכף מאוחר יותר, בעת הפריסה: ה-delta_indices חייב להיות הטווח הרציף שמתחיל באפס. חלון דליל כגון [0, 4, 8] נדחה, מכיוון שכל מה שבהמשך מאנדקס את הנתח החזוי באופן ליניארי ואחרת יבצע את השורות הלא נכונות.

שנו את delta_indices וחובה לייצר מחדש את הסטטיסטיקות

סטטיסטיקות הנורמליזציה, בפרט meta/relative_stats.json, מחושבות עבור אורך האופק שהיה לכם בעת יצירתן. קצרו את אופק הפעולה מ-16 ל-8 ללא יצירה מחדש והאימון ייכשל עם IndexError: boolean index did not match indexed array ... dimension is 8 but corresponding boolean dimension is 16. התיקון הוא פקודה אחת: python gr00t/data/stats.py --dataset-path <path> --embodiment-tag NEW_EMBODIMENT --modality-config-path examples/SO100/so100_config.py. הריצו אותה לאחר כל שינוי ב-delta_indices.

שלב 4: הסביבה

N1.7 העבירה את המאגר ל- ופייתון 3.12. הנתיב הישן של קונדה פלוס pip install -e . עדיין קיים בקטע מכווץ של קובץ ה-README, אך הוא מזהיר שתלויות GPU, כולל flash-attn ו-TensorRT, עשויות לדרוש התקנה ידנית. השתמש ב-uv אלא אם יש לך סיבה ספציפית שלא לעשות זאת. בנוגע ל-flash-attn, פרט אחד חוסך בלבול: תראה Installing flash-attn מודפס בכל uv run. הוא לא נבנה מחדש. uv מאמת מחדש גלגל מקושר ל-URL שכבר נשמר במטמון, וזה לוקח שתיים או שלוש שניות.

  1. 1
    התקן git-lfs, ולאחר מכן שכפל עם תת-מודולים

    git-lfs נדרש, לא אופציונלי. בלעדיו קבצי ה-parquet ב-demo_data/ יורדים כקובצי מצביע (pointer stubs), והרצת ההדגמה נכשלת על מערך נתונים שנראה קיים ברשימת הקבצים.

    bash
    sudo apt install git-lfs && git lfs install
    git clone --recurse-submodules https://github.com/NVIDIA/Isaac-GR00T
    cd Isaac-GR00T
  2. 2
    התקן uv וסנכרן את הסביבה

    ההתקנה המוגדרת כברירת מחדל מושכת את תלויות ה-GPU, כולל flash-attn ו-TensorRT. בתמונת A100 או H100 חדשה זהו השלב הבודד הארוך ביותר, לכן בצע אותו לפני שתתחיל לשים לב לכל דבר אחר.

    bash
    curl -LsSf https://astral.sh/uv/install.sh | sh
    sudo apt-get update && sudo apt-get install -y ffmpeg
    uv sync --python 3.12
    uv run python -c "import gr00t; print('GR00T installed successfully')"
  3. 3
    אמת מול Hugging Face

    בצע זאת לפני ההשקה הראשונה של האימון, לא לאחר שהוא נכשל שמונה דקות לתוך התהליך.

    bash
    uv run huggingface-cli login   # or: export HF_TOKEN=<your_token>
  4. 4
    בדיקת תקינות על נתוני הדגמה SO-100 המסופקים

    לפני שתתחיל לעבוד עם ההקלטה שלך, הרץ 2000 צעדים על demo_data/cube_to_bowl_5. אלה חמישה פרקים, זה מסתיים במהירות, וזה מוכיח את הסביבה ולא את הנתונים שלך. אם הרצה זו נכשלת, שום דבר שתעשה למערך הנתונים שלך לא יעזור.

    bash
    CUDA_VISIBLE_DEVICES=0 uv run python \
        gr00t/experiment/launch_finetune.py \
        --base-model-path nvidia/GR00T-N1.7-3B \
        --dataset-path demo_data/cube_to_bowl_5 \
        --embodiment-tag NEW_EMBODIMENT \
        --modality-config-path examples/SO100/so100_config.py \
        --num-gpus 1 \
        --output-dir /tmp/test_finetune \
        --max-steps 2000 \
        --global-batch-size 32 \
        --dataloader-num-workers 4
שתי מלכודות סביבה שנראות כמו באגים במודל

FFmpeg 8. torchcodec 0.8.0 תומך ב-FFmpeg 4 עד 7 בלבד, ואובונטו 25.10 וגרסאות מאוחרות יותר מגיעות עם גרסה 8. השגיאה היא Could not load libtorchcodec, שנראית כמו התקנה שבורה ולא כמו התנגשות גרסאות. התקן סביבת ריצה ישנה יותר, לדוגמה conda install -c conda-forge 'ffmpeg<8', והצב את הספריות שלה ב-LD_LIBRARY_PATH. CUDA_HOME אינו מוגדר. כוונון עדין נכשל לחלוטין. הרץ bash scripts/deployment/dgpu/install_deps.sh פעם אחת, או פשוט export CUDA_HOME=/usr/local/cuda.

שלב 5: פקודת ה-fine-tune וברירות המחדל האמיתיות של הדגלים שלה

החליפו את מערך הנתונים של ההדגמה בשלכם והוסיפו את ההגדרות שאתם באמת רוצים. להלן הצורה המלאה שהמאגר משתמש בה במדריך ה-new-embodiment שלו, כולל דגלי ההרחבה (augmentation) ושמירת נקודות הבקרה (checkpointing) שהדוגמה הקצרה ב-README משמיטה. זהו במובן הצר: עמוד השדרה השפתי והמקודד החזותי נשארים קפואים, ומה שמתאמן הוא המקרן (projector) וראש הפעולה של הדיפוזיה (diffusion action head).

bash
export NUM_GPUS=1
CUDA_VISIBLE_DEVICES=0 uv run python \
    gr00t/experiment/launch_finetune.py \
    --base-model-path nvidia/GR00T-N1.7-3B \
    --dataset-path ./my_dataset_lerobot \
    --embodiment-tag NEW_EMBODIMENT \
    --modality-config-path examples/SO100/so100_config.py \
    --num-gpus $NUM_GPUS \
    --output-dir /tmp/so100 \
    --save-total-limit 5 \
    --save-steps 2000 \
    --max-steps 20000 \
    --use-wandb \
    --global-batch-size 32 \
    --color-jitter-params brightness 0.3 contrast 0.4 saturation 0.5 hue 0.08 \
    --dataloader-num-workers 4
GPU יחיד. עבור שמונה כרטיסים, החליפו את המפעיל ב-uv run torchrun --nproc_per_node=8 --master_port=29500 וקבעו את --num-gpus 8. השתמשו ב-uv run torchrun, לא ב-torchrun לבד, אחרת תקבלו סביבה שגויה.
דגלברירת מחדל ב-FinetuneConfigמה הוא עושה
--global-batch-size64גודל אצווה כולל בכל ה-GPUs לפני צבירת גרדיאנטים. הדוגמאות המסופקות משתמשות ב-32.
--learning-rate1e-4אותו ערך ש-AY-Robots שולחת עבור המאמן groot1.7 שלה.
--max-steps10000סה"כ צעדי אופטימיזציה. עוטף ה-examples/finetune.sh גם כן מוגדר כברירת מחדל ל-10000.
--gradient-accumulation-steps1מכפיל את האצווה האפקטיבית. ערכים מעל 1 מפיקים אזהרה המציינת את הגודל המצטבר.
--save-steps and --save-total-limit1000 and 5תדירות שמירת נקודות בקרה, וכמה מהן נשמרות. ישנות יותר נמחקות.
--weight-decay and --warmup-ratio1e-5 and 0.05מוגדר במפורש גם על ידי examples/finetune.sh.
--state-dropout-prob0.2 in the CLI, 0.8 in the model configמשמיט באופן אקראי מצב פרופריוצפטיבי במהלך האימון. הורידו אותו אם המשימה שלכם נשענת על מצב זה.
--tune-llm and --tune-visualFalse and Falseעמוד השדרה נשאר קפוא כברירת מחדל.
--tune-projector and --tune-diffusion-modelTrue and Trueהמקרן וראש הפעולה של הדיפוזיה הם מה שבאמת מתאמן.
--use-percentilesTrueנרמול עם q01 ו-q99 במקום מינימום ומקסימום גולמיים.
--dataloader-num-workers2הטוען מבוסס CPU בתכנון. הדוגמאות מעלות זאת ל-4.
--seeddoes not existאין דגל seed בממשק שורת הפקודה הזה.

השורה האחרונה אינה טעות הקלדה. launch_finetune.py הוא CLI של tyro שנוצר מ-dataclass, ול-dataclass זה אין שדה seed. קובץ ה-README מציין בנפרד שונות של 5 עד 6 אחוזים בין הרצות, הנגרמת על ידי הגברת תמונה לא דטרמיניסטית. שתי הרצות עם דגלים זהים לא יפיקו נקודות ביקורת זהות, וזה חשוב מאוד כשמנסים להחליט אם שינוי היפרפרמטר עזר או אם היה מזל. לשם השוואה, המאמן של lerobot עצמו מוגדר כברירת מחדל ל-seed 1000, והמתכון של LeRobot GR00T מעביר --seed=42 במפורש.

אימות כבוי כברירת מחדל, והדגל המתועד אינו קיים ב-CLI זה

כוונון עדין רץ עם eval_strategy="no", כך שאין עקומת איבוד אימות כלל. מקבלים איבוד אימון וזהו. המדריך למימוש חדש אומר להפעיל זאת עם --eval-strategy steps --eval-steps 500, אך דגל זה אינו קיים ב-launch_finetune.py: ה-CLI נוצר על ידי tyro מה-dataclass FinetuneConfig, ו-eval_strategy, eval_steps ו-eval_batch_size הם שדות של TrainingConfig במקום זאת. ברירות המחדל שלהם שם הן "no", 500 ו-2. כדי להגיע אליהם, השתמש בנקודת הכניסה המלאה יותר gr00t/experiment/launch_train.py, כאשר הדגל המקונן הוא --training.eval-strategy. כך או כך, איבוד אימון יורד לבדו אומר מעט מאוד על הכללה, וזו בדיוק הסיטואציה המתוארת ב- האיבוד יורד אך המדיניות לא עושה כלום.

כמה עולה הרצה של 20000 צעדים

GR00T N1.7 דורש כרטיס של 80 GB, ולכן לשאלת העלות יש תשובה מצומצמת. ב-AY-Robots, המאמן groot1.7 רץ על שכבת A100 80 GB או H100 80 GB, כאשר הרצה אורכת 3 עד 6 שעות בעלות של 1.20 עד 2.00 USD לשעה בשוק הספוט. זה בערך 4 עד 12 USD עבור משימת ברירת המחדל של 20000 צעדים. אותה משימה ב- SmolVLA או ACT נוחתת על כרטיס של 24 GB בעלות של 0.30 עד 0.60 USD לשעה ו-1 עד 3 USD להרצה. זהו הפשרה האמיתית: GR00T עולה בערך פי ארבעה לכל ניסיון, ואי אפשר להריץ אותו על ה-4090 שמתחת לשולחן שלך.

מודלרמת GPUזמן ריצה אופייניעלות אופייניתמינימום פרקים
GR00T N1.7A100 80 GB או H100 80 GB3 to 6 hours4 to 12 USD50
GR00T N1.5A100 80 GB או H100 80 GB3 to 6 hours4 to 12 USD50
Pi0.5A100 80 GB או H100 80 GB3 to 6 hours4 to 12 USD50
SmolVLARTX 4090 או כל כרטיס 24 GB2 to 5 hours1 to 3 USD30
ACTRTX 4090 או כל כרטיס 24 GB2 to 5 hours1 to 3 USD50

מינימום ה-50-פרק הוא רף תחתון, לא יעד. השאלות הנפוצות של NVIDIA עצמה תובעניות יותר: בערך 100 מסלולים עבור איסוף והנחה פשוטים במיקום קבוע, 500 או יותר עבור סצנות מורכבות או מרובות שלבים, ו-100 עד 500 עבור מניפולציה עדינה. אם אתם נמצאים ב-20 פרקים, הקדישו את אחר הצהריים להקלטה במקום את הערב לכוונון. ה-מדריך איסוף הנתונים מכסה מה מבדיל פרק שימושי מפרק מבוזבז, הקלט את מערך הנתונים הראשון שלך היא הגרסה הקצרה, ו-איסוף נתונים SO-100 היא הגרסה הספציפית לזרוע.

מדריך האימון של AY-Robots עבור GR00T N1.7 על ה-SO-100, מציג את רצועת המפרט עם רמת GPU, פורמט מערך הנתונים הנדרש והגדרות ברירת המחדל של המאמן
המדריך /train/groot-n1-7-on-so-100 מציג את העובדות שהייתם משחזרים ידנית: רמת GPU, פורמט מערך נתונים, והגדרות ברירת המחדל המדויקות שהמאמן שולח.

שלב 6: הערכת לולאה פתוחה לפני שאתה נוגע בזרוע

אל תשים נקודת ביקורת על זרוע פיזית כדי לגלות אם האימון עבד. הרץ תחילה את הערכת הלולאה הפתוחה. היא מפעילה מחדש פרק מוקלט, מבקשת מהמודל פעולות בכל שלב, ומשרטטת את החיזוי מול אמת הקרקע עם MSE ו-MAE. זה לא עולה כלום ותופס את טעויות המיפוי משלבים 2 ו-3.

bash
uv run python gr00t/eval/open_loop_eval.py \
    --dataset-path ./my_dataset_lerobot \
    --embodiment-tag NEW_EMBODIMENT \
    --model-path /tmp/so100/checkpoint-20000 \
    --traj-ids 0 \
    --execution-horizon 16 \
    --steps 400 \
    --modality-keys single_arm gripper
הגרפים נוחתים ב-/tmp/open_loop_eval/traj_<id>.jpeg אלא אם כן תעביר את --save-plot-path. ברירות מחדל: --execution-horizon 16, --steps 200, --denoising-steps 4, --traj-ids 0.

המאגר מסרב במכוון לפרסם MSE יעד עבור נתונים מותאמים אישית, וזו ההחלטה הנכונה: המספר תלוי ביחידות הפעולה שלך, במשימה שלך ובגודל מערך הנתונים שלך, כך שסף שהועתק מזרוע של מישהו אחר אינו אומר כלום. מה שמשמעותי הוא המגמה. להלן הרצת הייחוס שהמאגר מתעד על H100 יחיד עם מערך הנתונים ההדגמתי של חמישה פרקים ו-2000 צעדים.

נקודת ביקורתMSE ממוצע על מסלול 0MAE ממוצע על מסלול 0
50087.55.63
100025.43.30
150013.22.18
200010.01.76

הצורה היא האות, לא הערכים המוחלטים. השגיאה אמורה לרדת בהתמדה ככל ש- מצטברים. בממוצע על פני כל חמשת פרקי האימון במקום מסלול 0 בלבד, נקודת הבדיקה הסופית של המאגר השיגה בערך 7.5 MSE ו-1.5 MAE, כך שאפילו הרצת הייחוס נקראת אחרת בהתאם לפרקים שאתה ממוצע. רשום את קו הבסיס שלך בפקודת ההדגמה הלא משונת לפני שאתה משנה משהו בנתונים שלך: אם אינך יכול לשחזר הרצה ידועה וטובה, אינך יכול להבחין בין טעות הגדרה לבעיית נתונים. המאגר גם ממפה את התסמינים הנפוצים לסיבות, וכל אחד מהם הוא תפעולי ולא באג במודל.

תסמיןגורם סביר
MSE שטוח או עולה בין נקודות בדיקהקצב למידה נמוך מדי, או שהנתונים אינם נטענים כלל. בדוק את --dataset-path ואת עובדי טוען הנתונים.
עקומת החיזוי שטוחה או קבועהמפתחות modality.json או --modality-config-path אינם תואמים. מפתחות הפעולה אינם ממופים.
MSE עצום, או אובדן NaN במהלך האימוןנורמליזציה של פעולה ומצב. ודא את meta/stats וכי טווחי הפעולה סבירים פיזית.
טוב על traj 0, גרוע על פרקים שלא נכללו באימוןמחסור בנתונים, לא באג. חמישה פרקי הדגמה אינם יכולים להכליל.

המסלול האחר: lerobot-train במקום Isaac-GR00T

הגרסה הנוכחית של LeRobot, 0.6.1 ב-PyPI מאז 3 באוגוסט 2026, מציעה דרך שנייה ושונה למדי לכייל את אותם משקלי בסיס. LeRobot חושפת את GR00T N1.7 כסוג מדיניות ומאמנת אותה דרך נקודת הכניסה שלה lerobot-train נקודת כניסה. שני דברים חשובים כאן. ה-CLI של LeRobot הוא סט של סקריפטים לקונסולה, אז כל דבר שאתה קורא שאומר python lerobot/scripts/train.py מיושן ולא יפעל. ו-LeRobot הסירה תמיכה ב-GR00T N1.5 לחלוטין, דוחה נקודות בדיקה ותצורות של N1.5 עם הערת הגירה, אז אם אתה צריך N1.5 דרך LeRobot עליך לקבע את lerobot==0.5.1, הגרסה האחרונה שתומכת בו, שפורסמה ב-7 באפריל 2026.

bash
pip install "lerobot[groot]" "lerobot[training]"
hf auth login

lerobot-train \
  --dataset.repo_id=$HF_USER/$DATASET_NAME \
  --dataset.image_transforms.enable=true \
  --policy.type=groot \
  --policy.device=cuda \
  --policy.base_model_path=nvidia/GR00T-N1.7-3B \
  --policy.embodiment_tag=new_embodiment \
  --policy.chunk_size=16 \
  --policy.n_action_steps=16 \
  --policy.use_relative_actions=true \
  --policy.relative_exclude_joints='["gripper"]' \
  --policy.use_bf16=true \
  --seed=42 \
  --batch_size=64 \
  --steps=20000 \
  --save_freq=5000 \
  --output_dir=$OUTPUT_DIR
מתכון GR00T N1.7 המובנה ב-LeRobot. שימו לב ל-relative_exclude_joints: התופסן אינו נכלל בפעולות יחסיות, וזו אותה החלטה ש-so100_config.py מקבל עם ActionRepresentation.ABSOLUTE.
היבטIsaac-GR00T launch_finetune.pylerobot-train --policy.type=groot
גרסת מערך הנתוניםLeRobot v2 בלבד, נדרשת המרהמערך נתונים מקורי של LeRobot, ללא שדרוג לאחור
מיפוי מודליותmeta/modality.json בתוספת קונפיגורציית נתונים בפייתוןאין modality.json; ההתנהגות נקבעת על ידי דגלי --policy.* בשורת הפקודה
Seedאין דגל seed כלל--seed, ברירת מחדל של LeRobot היא 1000
פעולות יחסיותActionConfig לכל מפתח בקונפיגורציית הנתונים--policy.use_relative_actions בתוספת --policy.relative_exclude_joints
תוצאות ייחוס שפורסמומגמת MSE בלולאה פתוחה של SO-100 על נתוני הדגמהחבילות LIBERO, ממוצע של 96.5 אחוזים על פני ארבע חבילות
נתיב פריסהrun_gr00t_server.py בתוספת eval_so100.py מעל ZMQlerobot-rollout, עם חלוקה לגושים בזמן אמת (queue_threshold צריך להישאר ב-5 או מתחתיו)
הרצת הכוונון העדין בעצמך
יתרונות
  • כל דגל גלוי וניתן לשינוי. אתה יכול לבטל את הקפאת המקודד החזותי, להזיז את state_dropout_prob, או לקצר את אופק הפעולה.
  • גרפי הלולאה הפתוחה הם קבצים מקומיים. השוואת checkpoint-5000 מול checkpoint-20000 היא פקודת shell.
  • אינך תלוי בפלטפורמה כלשהי שתשאר מקוונת, וה-checkpoint יושב על הדיסק שלך בפורמט סטנדרטי.
  • דוגמאות הבנצ'מרק של הריפו עבור LIBERO, SimplerEnv ו-DROID מספקות לך ריצות ידועות-טובות לשחזור לפני שאתה סומך על הנתונים שלך.
פשרות
  • הסביבה היא רוב העבודה. גרסת FFmpeg, CUDA_HOME, git-lfs, ה-backbone המגודר, torchcodec: אף אחד מאלה אינו בעיות מודל וכל אחד מהם עוצר את הריצה.
  • ההמרה מ-v3.0 ל-v2.1 דורשת סביבה וירטואלית נפרדת עם שלב התקנה משלה, והיא כותבת מחדש את ספריית מערך הנתונים שלך במקום.
  • השכרת GPU מתחילה בחיוב כשאתה מתחיל ניפוי באגים, לא כשהאימון מתחיל, ושום דבר לא עוצר את המופע כשהריצה מסתיימת.
  • אין seed פירושו אין שחזור ביט-אחר-ביט, בנוסף לשונות של 5 עד 6 אחוזים מריצה לריצה מהגברת נתונים בלבד.

שתי דרכים לקבל את אותה נקודת שמירה

אתה שוכר את ה-GPU ואתה הבעלים של כל שלב. באופן מציאותי, בפעם הראשונה זה לוקח אחר צהריים, ולאחר מכן עשרים דקות בכל פעם.

  1. הקלט פרקים עם lerobot-record על ה-SO-100. תקבל מערך נתונים של LeRobot v3.0.
  2. המר אותו ל-v2.1 עם scripts/lerobot_conversion/convert_v3_to_v2.py בסביבה וירטואלית משלו.
  3. כתוב meta/modality.json ותצורת מודליות של Python, הרשומה תחת EmbodimentTag.NEW_EMBODIMENT.
  4. שכור כרטיס 80 GB, שכפל עם submodules, בצע uv sync, בצע אימות מול Hugging Face.
  5. הרץ launch_finetune.py, ולאחר מכן open_loop_eval.py על מספר נקודות שמירה, והשווה את מגמת ה-MSE לפני נגיעה בחומרה.
  6. משוך את נקודת השמירה מהמכונה לפני שתהרוס את המופע, ולאחר מכן בנה את נתיב ההגשה לזרוע.
השלב שכולם שוכחים

העתק את נקודת השמירה מהמופע השכור לפני שתכבה אותו. --save-total-limit 5 פירושו גם שנקודות שמירה ישנות יותר נמחקות ככל שהאימון מתקדם, כך שנקודת השמירה שרצית בשלב 5000 עשויה לא להתקיים עוד בשלב 20000.

מטריצת האימון של AY-Robots עם חמישה מודלי מדיניות כשורות וארבע זרועות רובוטיות כעמודות, כאשר כל תא מקשר למדריך אימון ספציפי
מטריצת ה-/train: חמישה מודלים מול ארבע זרועות. שורת GR00T N1.7 מכסה גם את SO-101, Koch v1.1 ו-LeKiwi.

החזרת נקודת השמירה לזרוע

Isaac-GR00T משתמש בפיצול שרת-לקוח מעל ZMQ. המדיניות רצה על ה-GPU, ולקוח דק על מכונת הרובוט שולח תצפיות ומקבל חלקי פעולה. דוגמת ה-SO-100 שלמה מספיק כדי להעתיק: הפעל run_gr00t_server.py עם נקודת השמירה שלך ו--embodiment-tag NEW_EMBODIMENT, ולאחר מכן הרץ eval_so100.py בצד הרובוט עם היציאה הטורית, מזהה הרובוט, אינדקסי המצלמה והוראת השפה. שמות המצלמות בפקודה זו חייבים להתאים לשמות הידידותיים מ-modality.json שלך, לא למספרי התקני מערכת ההפעלה.

bash
# GPU side
uv run python gr00t/eval/run_gr00t_server.py \
  --model-path /tmp/so100/checkpoint-20000 \
  --embodiment-tag NEW_EMBODIMENT \
  --device cuda:0 \
  --host 0.0.0.0 --port 5555

# robot side, from gr00t/eval/real_robot/SO100
uv run --no-sync python eval_so100.py \
  --robot.type=so101_follower \
  --robot.port=/dev/ttyACM2 \
  --robot.id=orange_follower \
  --robot.cameras="{ front: {type: opencv, index_or_path: 6, width: 640, height: 480, fps: 30}, wrist: {type: opencv, index_or_path: 2, width: 640, height: 480, fps: 30}}" \
  --policy_host=localhost --policy_port=5555 \
  --lang_instruction="put the cube in the yellow bowl"
--execution-horizon שולט בכמה מהצעדים החזויים מבוצעים לפני תכנון מחדש. הוא חייב להיות לכל היותר action_horizon של המדיניות, ומספר זה הוא אורך ה-action delta_indices בתצורת המודליות שלך, לא של מודל הבסיס. תצורת SO-100 המסופקת חוזה 16, כך ש-16 הוא הגבול העליון שלך; נקודת הבדיקה הבסיסית nvidia/GR00T-N1.7-3B מוגדרת ל-40, ו-policy.md מציין בבירור שנקודות בדיקה מכווננות עשויות להיות שונות. חריגה ממנו תוביל ל-ValueError המציין את שני המספרים. 8 הוא הערך שהתיעוד מציע לפריסה בזמן אמת. שם הדגל הישן --action-horizon עדיין עובד אך מזהיר.
7.4 V, לא 12 V

בזמן שאתה מחבר מחדש את הזרוע: ה-SO-100 מפעיל סרווים של Feetech STS3215 על מסילת 7.4 V. הזנתם ב-12 V הורסת אותם, וזו טעות קלה אם בבעלותך גם LeKiwi, שבסיסו פועל ב-12 V בעוד שזרועו לא. בדוק את הספק הכוח לפני ההפעלה הראשונה, לא אחרי העשן. ראה את דף החומרה של SO-100 ואת SO-100 מול LeKiwi. אם הזרוע נדלקת אך דבר לא זז, סרוו לא מגיב הוא המקום להתחיל.

כעת החלק הכנה לגבי היכן המדיניות פועלת, מכיוון שלאימון והגשה יש סיפורי חומרה שונים. כוונון עדין דורש 40 GB או יותר. הסקה לא: קובץ ה-README מציין 16 GB או יותר ומזכיר במפורש את ה-RTX 4090, כך שכרטיס שכבר בבעלותך יכול להגיש נקודת בדיקה שהוא מעולם לא היה יכול לייצר. מה שמחליט אם המדיניות מרגישה מגיבה אינו VRAM, אלא היכן השרת ממוקם. ב-AY-Robots GR00T N1.7 הוא מבוסס ענן בלבד, כך שלולאת הבקרה משלמת על נסיעה הלוך ושוב באינטרנט ציבורי בנוסף ל-152 אלפיות השנייה לכל שלב פעולה, ורק SmolVLA ו- ACT פועלים גם מקומית. עבור איסוף והנחה איטיים, תא מרוחק הוא נסבל. עבור כל דבר תגובתי זה לא: המדיניות הופכת מהוססת באופן שנראה בדיוק כמו כשל אימון ואינו כזה. ACT ב-20 אלפיות השנייה לכל שלב פעולה הוא המודל הסובלני ביותר ללולאה הדוקה, SmolVLA יושב ב-245 אלפיות השנייה, ושום כמות של כוונון השהיה לא תחזיר נסיעה הלוך ושוב שכבר בוזבזה. הפעל את המדיניות הראשונה שלך עובר על צד ההגשה מקצה לקצה.

מה באמת משתבש

  • GatedRepoError בהרצה הראשונה. לא קיבלת גישה ל-nvidia/Cosmos-Reason2-2B, או שלא אימתת את זהותך. זה קורה לאחר ששעון ה-GPU כבר התחיל לפעול.
  • מערך נתונים נדחה בטעינה. כמעט תמיד מדובר במערך נתונים v3.0. המר אותו לגרסה קודמת. ראה מערך נתונים נדחה כ-v3.
  • IndexError לגבי מימדי בוליאניים לא תואמים. שינית את delta_indices ולא יצרת מחדש את הסטטיסטיקות.
  • חוסר זיכרון באצווה 32. צמצם את --global-batch-size והגדל את --gradient-accumulation-steps, או צמצם את --num-shards-per-epoch, מה שהקונפיגורציה מציעה במפורש כאשר VRAM מוגבל. ראה חוסר זיכרון במהלך אימון.
  • ההפסד יורד, המדיניות לא עושה כלום. אין חלוקת ולידציה כברירת מחדל, כך שעקומת אימון נקייה מוכיחה מעט מאוד. עמוד זה מכסה את האבחון.
  • עובד בהגדרה שלך ובשום מקום אחר. צפוי עם מערך נתונים קטן שצולם בתנאי תאורה אחד. NVIDIA ממליצה על הגברת רעידות צבע (colour jitter augmentation) בתוספת 20 עד 50 אפיזודות בתנאי תאורה שונים. עוד כאן.
  • התפסן (gripper) לעולם אינו נסגר כראוי. ודא שפעולת התפסן היא ABSOLUTE ומפרקי הזרוע הם RELATIVE, בסדר זה ב-action_configs. התפסן אינו נסגר מפרט את הסיבות האחרות.
  • מצלמה נופלת בשקט באמצע ההקלטה. האפיזודה עדיין נשמרת ומפתח הווידאו עדיין קיים, ולכן זהו מקרה מורכב. מצלמה לא מזוהה מכסה זאת.

האינדקס המלא של מצבי כשל נמצא ב-. אם אתה בוחר בין מודלים במקום לנפות באגים באחד מהם, ו- כוללים מספרי ביצועים עם מקורות מצורפים, ו- היא ההשוואה שרוב האנשים באמת צריכים, מכיוון שהיא הבחירה בין מודל שאתה יכול לאמן על הכרטיס שמתחת לשולחן שלך לבין מודל שאתה צריך לשכור צומת 80 GB כדי לכוונן אותו. לרקע מדוע מודלים אלה מתנהגים כפי שהם, ה- ו- שווים קריאה קודם. ואם עדיין אין לך זרוע, משדרת SO-100 פיזית ללא הרשמה.

כמה אפיזודות אני צריך לפני שכדאי לכוונן את GR00T N1.7?

AY-Robots קובעת רף מינימלי של 50 אפיזודות עבור מאמן ה-groot1.7. השאלות הנפוצות של NVIDIA עצמה תובעניות יותר: בערך 100 מסלולים עבור פעולת 'הרם והנח' פשוטה במיקום קבוע, 500 או יותר עבור סצנות מורכבות או מרובות שלבים, ו-100 עד 500 עבור מניפולציה עדינה. מתחת ל-50, כמעט תמיד עדיף להקליט יותר נתונים מאשר לכוונן היפרפרמטרים. אם ההצלחה מתייצבת לאחר מכן, NVIDIA ממליצה על HG-DAgger: הרץ את המדיניות, התערב כשהיא נכשלת, והוסף את התיקונים הללו למערך הנתונים.

מדוע מערך הנתונים שלי נכשל בטעינה, ואיך אני יודע איזו גרסה הוא?

פתח את meta/info.json וקרא את codebase_version. ה-CODEBASE_VERSION הנוכחי של LeRobot ב-main הוא v3.0, כך שכל דבר שהוקלט עם שרשרת כלים עדכנית הוא v3.0, וטוען ה-GR00T מצפה ל-v2. המר באמצעות scripts/lerobot_conversion/convert_v3_to_v2.py ממאגר Isaac-GR00T, אשר כותב codebase_version: v2.1 לתוך מערך הנתונים המומר. הסקריפט רץ בסביבה וירטואלית משלו מכיוון שהוא זקוק לגרסת lerobot שונה מזו ש-GR00T מקבע.

האם אני יכול לכוונן את GR00T N1.7 על RTX 4090?

לא. NVIDIA ממליצה על 40 GB או יותר של VRAM לכוונון עדין ומציינת צומתי H100 או L40; כרטיסים אחרים עובדים אך לוקחים הרבה יותר זמן. ל-4090 יש 24 GB. AY-Robots מציעה את GR00T N1.7 רק בשכבת A100 80 GB ו-H100 80 GB מאותה סיבה. הסקה (Inference) היא סיפור אחר: 16 GB מספיקים כדי לשרת את המודל, כך ש-4090 יכול להריץ מדיניות שהוא לא יכול לאמן. אם אתה רוצה VLA שאתה יכול לאמן על 24 GB, זה SmolVLA עם כ-450 מיליון פרמטרים או ACT עם כ-80 מיליון.

מדוע שתי הרצות עם דגלים זהים נותנות נקודות שמירה שונות?

מכיוון של-launch_finetune.py אין seed. זהו CLI של tyro שנוצר מ-dataclass שאינו מכיל שדה seed, כך ששום דבר לא מקבע את ה-RNG. המאגר מציין בנפרד שונות של 5 עד 6 אחוזים בין הרצות הנגרמת על ידי הגברת תמונה לא דטרמיניסטית. אם שחזוריות חשובה, השתמש בנתיב LeRobot במקום זאת: lerobot-train מקבל --seed והמתכון המפורסם של GR00T מעביר --seed=42.

האם עלי להשתמש ב-Isaac-GR00T או ב-lerobot-train?

השתמש ב-Isaac-GR00T אם אתה רוצה את מימוש הייחוס, שליטה פר-מפתח על ייצוג פעולה, ייצוא TensorRT, או את דוגמאות הבנצ'מרק לשחזור לפני שאתה סומך על הנתונים שלך. השתמש ב-lerobot-train אם מערך הנתונים שלך הוא כבר LeRobot v3.0 ואתה מעדיף לא להמיר אותו, אם אתה רוצה seed, או אם שאר הערימה שלך היא כבר LeRobot. שניהם מכווננים את אותם משקלי nvidia/GR00T-N1.7-3B. שים לב ש-LeRobot הפסיקה לחלוטין את התמיכה ב-GR00T N1.5: נקודות שמירה של N1.5 נדחות עם הערת הגירה, ואתה צריך לקבע את lerobot==0.5.1 כדי להמשיך להשתמש בהן.

האם אני באמת צריך מצלמת פרק כף יד בנוסף למצלמה קדמית?

תצורת ה-SO-100 המסופקת משתמשת בשתיהן, ו-modality.json ממפה את המצלמה הקדמית ומצלמת פרק כף היד כמפתחות וידאו נפרדים. אתה יכול לאמן עם מצלמה אחת, וטבלת ההשהיה של כרטיס המודל נמדדת עם מצלמה אחת, אך תצוגת פרק כף היד היא זו שנותנת למדיניות מידע שימושי על התפסן ברגע המגע. אם התפסן נסגר בזמן הלא נכון בהרצות שלך, מצלמת פרק כף יד חסרה או מכוונת רע היא אחד הדברים הראשונים שיש לבדוק.

כוונן את GR00T N1.7 על ה-SO-100 שלך מבלי לבנות את הסביבה תחילה

בחר מודל, מערך נתונים והיפרפרמטרים בטופס. ה-backend שוכר A100 80 GB או H100 בשוק הספוט, מריץ את המאמן עם אצווה 32, קצב למידה 1e-4 ו-20000 צעדים, וכותב נקודות שמירה לאחסון אובייקטים. בערך 4 עד 12 דולר ארה"ב לכל הרצה.

פתח את מדריך האימון של GR00T N1.7

Ready for high-quality robotics data?

AY-Robots connects your robots to skilled operators worldwide.

Get Started