LeRobot documentation

Dòng chảy bộ dữ liệu huấn luyện

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Dòng chảy bộ dữ liệu huấn luyện

Chế độ streaming tập dữ liệu trong quá trình huấn luyện cho phép lerobot-train sử dụng LeRobotDataset v3 mà không cần tải trước toàn bộ dữ liệu Parquet và video. Bật tính năng này thông qua công tắc công khai hiện có:

lerobot-train \
  --dataset.repo_id=OWNER/DATASET \
  --dataset.streaming=true \
  --policy.type=act \
  --output_dir=outputs/train/act_streaming

Tính năng này độc lập với --dataset.streaming_encoding=true. streaming_encoding kiểm soát cách các video được ghi trong khi thu hình; dataset.streaming kiểm soát cách một tập dữ liệu hiện có được đọc trong quá trình huấn luyện. Bộ mã hóa ghi hình và rollout không được sử dụng bởi đường dẫn huấn luyện này.

Cách một epoch được đọc

Mỗi rank phân phối sở hữu một tập hợp các episode hoàn chỉnh, cân bằng theo khung hình và có tính tất định. Mỗi pool bao phủ chính xác cho mỗi worker của DataLoader trộn phần của worker đó trong các episode này, đảm bảo mỗi khung hình được chọn được truy cập đúng một lần trong mỗi epoch bao phủ. Các cột Parquet và các khoảng byte của MP4 nén được nạp trước từ cùng một biên giới chấp nhận nhận thức về byte. Các cửa sổ lịch sử thời gian và tương lai được giải quyết bên trong episode hoàn chỉnh, bao gồm cả các mặt nạ đệm biên giới giống như khi nạp theo kiểu map.

Hành vi LeRobotDataset theo phong cách map mặc định không thay đổi khi --dataset.streaming=false.

Workers, shards và độ song song

Mỗi rank sở hữu một shard cân bằng khung hình của các episode hoàn chỉnh. Bên trong một rank, --num_workers đặt số lượng tiến trình worker của DataLoader, giống như với các dataset kiểu map. Mỗi worker sở hữu một phần rời rạc, cân bằng khung hình của các episode thuộc rank đó, với pool bao phủ chính xác riêng, phần ngân sách byte riêng và các pool thread riêng:

Giai đoạnSự đồng thờiCài đặt
Phân mảnh theo rankMột shard tập hoàn chỉnh rời rạc cho mỗi rankKích thước thế giới phân tán
Công nhân DataLoaderMột phần rời rạc của shard rank cho mỗi worker--num_workers
Lấy tậpCác hàng Parquet và các khoảng byte MP4, song songmax_num_shards, được đặt từ --num_workers
Lắp ráp và giải mã mẫuCác cửa sổ thời gian và khung hình video, song song--dataset.streaming_decode_threads
Bộ đệm mẫu có thứ tựCác mẫu đã giải mã được giữ phía trước, theo thứ tự của bộ lập kế hoạch--dataset.streaming_decoded_queue_size

Vì sao cần nhiều worker. Việc lắp ráp mẫu và bàn giao batch chạy mã Python, và một tiến trình chỉ chạy mã Python trên một luồng tại một thời điểm (do GIL). Với một worker, các luồng giải mã của một rank phải chờ nhau, khiến rank chỉ sử dụng khoảng 2 nhân CPU. Mỗi worker là một tiến trình riêng biệt, nên N worker sẽ lắp ráp và giải mã các mẫu song song.

Pool size và độ đa dạng của batch. streaming_episode_pool_size thiết lập pool của mỗi worker. Nếu bạn không thiết lập nó, rank sẽ trộn 32 episodes và mỗi trong số N workers nhận được 32/N trong số đó. Mỗi worker cũng prefetch streaming_prefetch_episodes episodes và là một tiến trình Python riêng biệt, do đó càng nhiều worker thì càng dùng nhiều bộ nhớ: trên một dataset với 3 camera, 4 workers dùng khoảng 8 GB tổng cộng, so với khoảng 3 GB khi chỉ có một worker. DataLoader lấy mỗi batch từ một worker, do đó một batch sẽ trộn các episodes từ pool của một worker. Pool lớn hơn sẽ trộn nhiều episodes hơn trong mỗi batch, nhưng dùng nhiều bộ nhớ hơn và lấy nhiều dữ liệu hơn trước mẫu đầu tiên.

Hạn chế. Ngân sách byte (streaming_byte_budget_gb) và video_decoder_cache_size được chỉ định rõ ràng vẫn được tính trên mỗi rank: mỗi worker nhận 1/N của chúng. Một worker cần ít nhất một episode, do đó lerobot-train sử dụng tối đa số worker bằng số episode mà rank có. --num_workers=0 giữ dataset trong tiến trình huấn luyện. Ở đó, luồng huấn luyện áp dụng các biến đổi hình ảnh, nên cùng một --seed sẽ cho ra cùng các biến đổi.

MP4 sidecars và lần chạy đầu tiên

Video streaming sử dụng một tệp sidecar chỉ mục MP4. Khi khởi tạo Dataset, hệ thống trước tiên kiểm tra bộ nhớ đệm cục bộ theo khóa revision, sau đó tìm một sidecar đã phát hành hợp lệ. Nếu cả hai đều không khả dụng, LeRobot sẽ xây dựng sidecar cục bộ trong khi giữ khóa tiến trình và cài đặt nó một cách nguyên tử. Một lần xây dựng thất bại hoặc bị gián đoạn sẽ không thay thế tệp hợp lệ trước đó. Các tiến trình khác cần cùng một sidecar sẽ chờ khóa trong tối đa --dataset.streaming_sidecar_lock_timeout_s (mặc định là 30 phút). Hãy tăng giá trị này cho các dataset lớn cần nhiều thời gian hơn để lập chỉ mục.

Việc đọc payload trên Hub được cố định vào commit của bản chụp metadata. Các chỉ mục Bucket được kiểm tra đối chiếu với danh sách đối tượng mới nhất, bao gồm cả các băm nội dung, do đó việc thay thế một video tại cùng một đường dẫn sẽ làm vô hiệu hóa sidecar của nó ngay cả khi kích thước tệp không thay đổi. Việc liệt kê này làm tăng khối lượng công việc khi khởi động, nhưng không tải xuống các payload video. Hãy giữ nguyên metadata và payload trong suốt một lần chạy. Các hệ thống tệp từ xa chung chung không có danh tính đối tượng ổn định sẽ xây dựng lại chỉ mục của chúng mỗi lần mở. Các sidecar Bucket hiện có không có dấu vân tay đối tượng sẽ được xây dựng lại cục bộ một lần; việc xuất bản sidecar đã cập nhật vẫn là một hành động rõ ràng của người bảo trì.

Training chỉ ở chế độ đọc: nó không bao giờ tải lên một tệp sidecar hay sửa đổi kho dữ liệu. Trên một cụm có bộ nhớ đệm cục bộ theo nút, công việc đầu tiên có thể xây dựng một lần cho mỗi nút. Một bộ nhớ đệm LeRobot dùng chung sẽ tránh được sự trùng lặp đó.

Việc xây dựng sidecar ghi mỗi chỉ mục nguồn đã hoàn thành vào một lưu trữ tạm thời. Nó giữ lại tối đa số lượng kết quả phân tích được cấu hình. Bộ nhớ mảng phụ thuộc vào các nguồn đồng thời lớn nhất; metadata của lưu trữ vẫn tăng theo số lượng nguồn. Sử dụng --workers để đặt mức độ đồng thời phân tích khi bạn chạy lerobot-build-mp4-sidecar. Một lần xây dựng thất bại sẽ giữ lại sidecar trước đó.

Các kho lưu trữ NPZ schema-3 đã xuất bản giữ nguyên các mảng số nguyên int64 chính tắc. Việc mở lần đầu tiên sẽ chuyển đổi kho lưu trữ thành một chỉ mục ánh xạ bộ nhớ chỉ đọc tại $HF_LEROBOT_HOME/streaming-indexes. Chỉ mục dẫn xuất sử dụng các kiểu số nguyên chính xác nhỏ nhất. Nó lưu trữ một lần cho mỗi giá trị thời lượng, độ lệch cấu thành, kích thước hoặc độ lệch byte không đổi. Các quan điểm mảng chỉ đọc giữ nguyên số lượng mẫu logic. Các mốc thời gian trình bày giữ nguyên các giá trị float64 chính xác. Các mảng mẫu đồng bộ giữ nguyên lưu trữ đặc.

Chỉ mục dẫn xuất sử dụng một thế hệ cache riêng biệt. Các trình đọc cũ giữ nguyên định dạng cache hiện có. Lần mở đầu tiên với trình đọc mới có thể chuyển đổi kho lưu trữ một lần; các lần mở sau đó sẽ tái sử dụng nó. Quá trình chuyển đổi sử dụng khóa tiến trình và thay thế nguyên tử. Các rank chia sẻ cache sẽ tái sử dụng các trang dựa trên tệp giống nhau. Mỗi rank chỉ xây dựng các bản ghi cho các tệp nguồn được sử dụng bởi các episode của nó. Các thế hệ cache cũ và mới có thể yêu cầu thêm dung lượng đĩa. Việc thay thế một tệp sidecar tạo ra một thế hệ bất biến mới mà không làm vô hiệu hóa các trình đọc đang hoạt động.

Điều này không làm cho tất cả các metadata có kích thước cố định: metadata của episode và bảng span vẫn tăng theo bộ dữ liệu, và các shard rank đã xáo trộn có thể chạm đến các tệp nguồn chồng lấn. Các trang được ánh xạ nằm trong OS cũng được tính vào RSS; hãy sử dụng proportional set size (PSS) khi đo bộ nhớ được chia sẻ bởi các rank. Việc đọc Parquet sẽ loại bỏ các nhóm hàng (row groups) bằng cách sử dụng thống kê của episode và sau đó lọc để lấy episode hoàn chỉnh. Các nhóm không có thống kê vẫn là ứng viên, do đó các tệp không có giới hạn hữu ích vẫn có thể yêu cầu đọc dự phóng toàn bộ tệp.

Người duy trì bộ dữ liệu có thể xây dựng sidecar trước:

lerobot-build-mp4-sidecar \
  --repo-id=OWNER/DATASET \
  --revision=COMMIT_SHA \
  --data-root=hf://datasets/OWNER/DATASET@COMMIT_SHA \
  --output=/tmp/dataset-mp4-sidecar.npz

Việc xuất bản luôn được thực hiện một cách rõ ràng. Chỉ thêm --push sau khi đã xác thực sidecar của bộ dữ liệu hoàn chỉnh. Không thể xuất bản các sidecar của tập con.

Đối với kho dữ liệu, --push sẽ tạo hoặc cập nhật nhánh lerobot-sidecars chuyên dụng. Nhãn/nhánh dữ liệu nguồn không bị thay đổi. Quá trình huấn luyện sẽ tìm kiếm tại đó một chỉ mục được gắn với commit nguồn video đã cố định và xác thực nó trước khi sử dụng. Một tag và commit đã được phân giải của nó sẽ chia sẻ cùng một chỉ mục đã công bố; các bộ nhớ đệm cục bộ được gắn khóa theo phiên bản hiện có vẫn có thể tái sử dụng. Các bucket vẫn công bố trực tiếp dưới meta/mp4-sidecars/. Việc công bố yêu cầu quyền ghi vào kho hoặc bucket; huấn luyện chỉ cần quyền đọc và không bao giờ tạo nhánh hoặc tải lên tệp.

Sidecar schema v3 bảo toàn thời điểm tổng hợp MP4 và các chỉnh sửa độ trễ mã hóa, bao gồm cả video có B-frame. Các sidecar cũ được xây dựng lại tự động vào một mục cache riêng được đánh dấu theo phiên bản; chúng cũng phải được xây dựng lại trước khi công bố rõ ràng. Các video được sắp xếp lại bao gồm phần cuối của GOP cuối cùng trong mỗi khoảng được lấy để chỉ số khung đã giải mã vẫn liên tục. Các dòng thời gian chỉnh sửa MP4 bị lặp lại hoặc có tốc độ không đơn vị sẽ bị từ chối thay vì âm thầm trả về các khung không căn chỉnh chính xác.

Cấu hình

Mặc định trong môi trường sản xuất là:

Tùy chọnMặc địnhÝ nghĩa
streaming_episode_pool_size32 / N mỗiSố tập hoàn chỉnh tối đa được trộn bởi mỗi worker
streaming_sampling_strategyremainingTrọng số khung còn lại hoặc round_robin xáo trộn
streaming_prefetch_episodes8Các tập được lấy trước cho mỗi pool của worker
streaming_byte_budget_gb8Số byte MP4 tổng hợp tối đa trên mỗi rank
streaming_decode_threads2Công nhân lắp ráp mẫu song song và giải mã video
streaming_decoded_queue_size8Các mẫu đã giải mã được đệm trước, theo thứ tự của bộ lập kế hoạch
video_decoder_cache_sizepool × camerasGiới hạn LRU của bộ giải mã video mở cho mỗi worker
streaming_native_http_connectionsunsetGiới hạn kết nối HTTP bản địa cho mỗi rank
streaming_native_http_subranges1Các khoảng con đồng thời cho mỗi thao tác đọc phạm vi HTTP bản địa
streaming_sidecar_lock_timeout_s1800Số giây để chờ một lần build sidecar khác
max_num_shards (--num_workers)16Số tập được lấy đồng thời trên mỗi worker

Tất cả các tùy chọn ngoại trừ max_num_shards là các cờ --dataset.*. max_num_shards là một tham số của StreamingLeRobotDataset; lerobot-train sẽ đặt giá trị này từ --num_workers (ít nhất là 1).

Để trộn các episode đều hơn, hãy chọn --dataset.streaming_sampling_strategy=round_robin. Mỗi vòng sẽ xáo trộn các episode đang hiện diện và lấy mẫu một khung hình đã xáo trộn từ mỗi episode; các episode được đưa vào trong một vòng sẽ tham gia vào vòng tiếp theo. Cả hai chiến lược đều giữ nguyên độ bao phủ epoch đúng một lần và các giới hạn tài nguyên như nhau. Không chiến lược nào là hoán vị đồng nhất toàn cục: round-robin ưu tiên các episode ngắn hơn trong các tiền tố hữu hạn và có thể làm tăng sự thay đổi của bộ giải mã cũng như giảm thông lượng. Thứ tự được lấy từ --seed (mặc định là 1000), cùng với việc khởi tạo chính sách và các trình tạo ngẫu nhiên có seed khác. Các seed khác nhau sẽ cho ra thứ tự episode và anchor khác nhau, và cùng một seed sẽ lặp lại thứ tự đó. --seed=null sử dụng seed streaming cố định là 42. Hãy giữ nguyên chiến lược, --seed và các cài đặt pool khi tiếp tục từ một checkpoint. Checkpoint lưu trữ seed, vì vậy --resume thông thường sẽ giữ nguyên thứ tự. Một checkpoint từ lần chạy bắt đầu trước khi --seed được áp dụng cho dataset streaming đã sử dụng seed 42 cho thứ tự của nó: hãy truyền --seed=42 khi bạn tiếp tục nó để giữ nguyên thứ tự đó.

Bộ tập hợp episode đang hoạt động bị giới hạn bởi cả số lượng episode và kích thước mini-MP4 tổng hợp chính xác được tính từ sidecar. Một episode lớn hơn ngân sách rank hoàn chỉnh sẽ thất bại trước khi quá trình huấn luyện lấy payload của nó. Các khoản đặt chỗ bao gồm các lượt fetch đang chờ, các lượt prefetch đã hoàn tất và các episode vẫn đang được giải mã. Khi ngân sách đã đầy, prefetch suy đoán sẽ tạm dừng và việc chấp nhận thay thế sẽ chờ đến khi lần giải mã cuối cùng giải phóng byte của nó. EpisodeByteCache.reserved_bytes báo cáo các khoản đặt chỗ này; resident_bytes báo cáo tất cả các payload đã hoàn tất, ngay cả trước khi mẫu đầu tiên của chúng được yêu cầu.

Đây là ngân sách cho payload nén, không phải giới hạn RSS của tiến trình: các bộ đệm tạm thời cho range-fetch/tổng hợp, trạng thái bộ giải mã, bảng Parquet và các tensor đã giải mã cần thêm bộ nhớ. Bộ LRU của bộ giải mã và hàng đợi mẫu đã giải mã có các giới hạn riêng biệt. Bắt đầu với một pool hoặc ngân sách nhỏ hơn trên các máy chủ bị hạn chế bộ nhớ:

lerobot-train \
  --dataset.repo_id=OWNER/DATASET \
  --dataset.streaming=true \
  --dataset.streaming_episode_pool_size=16 \
  --dataset.streaming_prefetch_episodes=4 \
  --dataset.streaming_byte_budget_gb=4 \
  --dataset.streaming_decode_threads=2 \
  --dataset.streaming_decoded_queue_size=8 \
  --num_workers=4 \
  --policy.type=act \
  --output_dir=outputs/train/act_streaming

Đối với một bộ dữ liệu hoàn chỉnh được lưu trữ trong một HF Storage Bucket, hãy sử dụng định danh của bucket và loại kho, hoặc truyền URI của bucket dưới dạng --dataset.root=hf://buckets/OWNER/BUCKET. Các tệp metadata (meta/), Parquet và video phải có mặt ở gốc của bucket đó:

lerobot-train \
  --dataset.repo_id=OWNER/BUCKET \
  --dataset.repo_type=bucket \
  --dataset.streaming=true \
  --policy.type=act \
  --output_dir=outputs/train/act_bucket_streaming

Bộ dữ liệu trên Hub sử dụng repo_type=dataset theo mặc định. Đối với một bộ dữ liệu cục bộ hoàn chỉnh, hãy đặt --dataset.root thành thư mục của nó. Quá trình huấn luyện sẽ phân giải metadata và payload từ cùng một nguồn; không cần cờ vị trí payload streaming riêng biệt.

Tiếp tục và trộn di trú

Trình đọc streaming trước đó sử dụng bộ đệm xáo trộn hàng có giới hạn. Trình đọc episode thay vào đó có thứ tự bao phủ chính xác mang tính tất định, được suy ra từ seed và epoch. Khôi phục checkpoint sẽ khôi phục độ lệch mẫu cho mỗi rank bằng cách sử dụng kích thước batch của checkpoint. Với nhiều worker, mỗi worker sẽ suy ra độ lệch riêng của nó từ đó, vì DataLoader lấy các batch từ các worker của nó theo lượt. Việc thay đổi kích thước world phân tán, kích thước batch hoặc --num_workers sẽ làm thay đổi quyền sở hữu hoặc ranh giới batch. Để so sánh chính xác từng mẫu, hãy khôi phục với cùng kích thước world, kích thước batch và số lượng worker. Giữ nguyên mức độ đồng thời fetch nội bộ khi so sánh hiệu năng.

Metadata của checkpoint không xác định được sampler đa worker trước đó. Các checkpoint của nó không thể được phân biệt một cách đáng tin cậy bằng các kiểm tra world-size và batch-size, và không được sử dụng để tiếp tục streaming chính xác theo mẫu. Hãy bắt đầu một lần chạy mới từ trọng số chính sách đã lưu của chúng. Cam kết về việc tiếp tục liên quan đến thứ tự của anchor, không phải việc phát lại từng bit của các biến đổi ảnh ngẫu nhiên. Các biến đổi ảnh ngẫu nhiên được thực hiện trên các luồng giải mã, song song với việc giải mã, do đó một seed cố định sẽ không tái tạo được cùng các phép tăng cường từ lần chạy này sang lần chạy khác.

Xử lý sự cố

Triệu chứngCần làm gì
Lô đầu tiên mất nhiều thời gianKiểm tra nhật ký cho một bản build sidecar. Tái sử dụng bộ nhớ đệm chung hoặc công bố rõ ràng một sidecar hoàn chỉnh đã được xác thực.
Khóa sidecar hết thời gian chờMột tiến trình khác có thể vẫn đang lập chỉ mục cùng một phiên bản. Hãy xác nhận tiến trình đó hoạt động bình thường trước khi xóa khóa đã cũ.
Một rank không sở hữu dữ liệuGiảm số lượng rank để mỗi rank sở hữu ít nhất một episode được chọn.
Ngân sách byte đã bị vượt quáGiảm pool episode, tăng ngân sách byte cho mỗi rank, hoặc sử dụng bố cục payload với khoảng episode nhỏ hơn.
Đọc từ xa không thể xác thựcĐảm bảo token Hugging Face hoặc thông tin xác thực fsspec khả dụng cho mọi worker. Sidecar không bao giờ nhúng thông tin xác thực.
Tốc độ bổ sung hàng caoSo sánh thời gian chờ batch p95/p99, giảm xung đột mạng, tăng dần mức prefetch, kiểm tra xem sidecar có khớp với revision hay không.
Update on GitHub