L5Kit, Ray, 그리고 W&B로 확장하는 자율주행 차량 모션 예측
이 튜토리얼에서는 W&B로 자율주행 차량의 주행 궤적 예측 모델을 손쉽게 구성하고 계측하는 방법과, Ray를 사용해 이를 확장하는 방법을 보여드립니다. 이 글은 AI 번역본입니다. 오역이 있을 수 있으니 댓글로 자유롭게 알려주세요.
Created on September 12|Last edited on September 12
Comment
소개
우리는 운전의 진정한 복잡성을 당연하게 여기는 경향이 있습니다. 운전을 할 때 우리는 매분 수십 가지의 작은 결정을 내립니다. 방향지시등을 켜고, 백미러를 확인하고, 앞차와의 거리를 조금 더 두기 위해 브레이크를 밟는 것까지 모두 포함해서요.
자율주행 모델도 똑같은 일을 해내야 하며, 이는 곧 한 개의 모델이나 한 명의 엔지니어로는 결코 충분하지 않다는 뜻입니다. 옛말에 이런 말이 있죠. “한 아이를 키우려면 온 마을이 필요하다.” 이 경우에는 데이터와 인접한 여러 분야의 실무자들이 상호 의존적으로 협업하는 “마을”이 필요합니다. 이들이 함께 만들어야 하는 모델은 다음과 같습니다.
- 충돌 없이 성능이 좋은 효율적인 모델을 확보하기 위해 자주 반복하며 개선합니다
- 강력한 감사 가능성을 위해 추적·기록되며, 모델을 “디버깅”하는 과정이 가능해집니다
- 우리가 학습한 모델을 다른 다운스트림 팀들이 이해하고 활용할 수 있도록, 그들에게 가장 적합한 맥락과 함께 제공될 수 있습니다.
Weights & Biases와 함께 사용하면 Ray, 우리 AV 조직 전반의 모든 페르소나, 실행 흔적, 결과를 포괄적으로 기록·관리할 수 있도록 실험 과정을 확장하는 방법을 배워봅니다. 이를 위해 사용합니다 Lyft Level 5에서 공개한 실제 데이터셋 (리프트의 자율주행 부문)
목차
소개목차 배경 링크:먼저 알아보기: 주행 궤적 예측이란 무엇일까? 🤔주행 궤적 예측 🤝 Lyft의 오픈 L5 데이터셋딥러닝을 활용해 주행 궤적 예측을 어떻게 해결할 수 있을까요?PyTorch의 L5Kit 모델주행 궤적 예측을 위한 자율주행차 학습 🚖Ray로 하드웨어 활용 극대화학습 출력!결론관련 자료
배경 링크:
레벨 5 연구팀
라시미 마르가니
💡
먼저 알아보기: 주행 궤적 예측이란 무엇일까? 🤔
주행 궤적 예측은 자율주행차 주변 환경에서 자동차, 자전거 이용자, 보행자가 어떻게 움직일지를 파악하는 기계학습 과제이다. 이는 다음과 다르다 객체 감지, 여기서는 모델이 이동 경로를 추적하기보다 물체를 식별하는 데 사용된다.
또한 우리 차량의 의사결정 과정인 계획(planning)은 예측 과제와는 다르지만 서로 밀접한 관련이 있음을 유의하자.

자율주행 스택의 세 가지 핵심 구성요소: 인지(차 주변에 무엇이 있는가?), 예측(다음에 무엇이 일어날까?), 계획(차가 무엇을 해야 하는가?).

예시 상황: 자율주행차가 비보호 좌회전을 수행하려면, 마주 오는 차량이 우회전을 할지 직진해 좌회전을 방해할지를 알아야 한다.
주행 궤적 예측 🤝 Lyft의 오픈 L5 데이터셋

팔로알토에서 우리 자율주행차 플릿이 수집한 1,000시간 분량 주행 데이터를 담은 Level 5 Prediction Dataset 스냅샷.
예측 데이터셋은 서로 다른 시점마다 차량 주변 세계를 기록한다. 각 타임스탬프에는 다음이 포함된다:
- 프레임 한 개 차량 자체에 대한 기록이다. 해당 시점의 위치와 방향, 그리고 주변에서 감지된 모든 에이전트와 신호등 목록이 포함된다.
- 에이전트 한 개 세상 속에서 움직일 수 있는 개체이다. 에이전트에는 클래스(자동차, 보행자 등)와 위치 정보가 라벨링된다. 에이전트는 연속된 프레임 사이에서 추적되는 고유 ID도 가진다.
AV 데이터를 다룰 때 흔히 선택하는 방식은 시스템 입력으로 탑다운(조감도, BEV) 래스터화를 사용하는 것입니다. 장면을 위에서 내려다본 형태로 표현하기 때문에 입력과 출력의 좌표계가 동일해져 모델을 구축하기가 쉬워집니다.
래스터화라고 불리는 데이터 전처리 기법은, 이 경우 센서 데이터와 같은 다른 객체로부터 이미지를 생성하는 과정이다
💡

데이터셋에서 자율주행차 주변의 다른 에이전트 위치를 포착한 주행 장면 예시.
입력 데이터
시맨틱 뷰와 위성 뷰의 경우:
🍀(초록) = 자율주행차(자차)
🐷(분홍) = 자율주행차 경로(궤적)
🔵(파랑) = 다른 에이전트(자동차, 자전거 등)
보케 뷰의 경우:
🐙(빨강) = 자차
🔵(파랑) = 다른 에이전트
아래 표의 아이콘을 클릭해 자율주행 차량 주행 장면의 다양한 애니메이션을 가장 잘 볼 수 있는 뷰로 열어 보세요. GIF 🎥뿐 아니라 Bokeh를 통해 주행 장면을 자유롭게 탐색할 수 있는 대화형 도구 🤳🏽도 제공합니다.
💡
1 of 10
딥러닝을 활용해 주행 궤적 예측을 어떻게 해결할 수 있을까요?
먼저, 표준 CNN 아키텍처를 변형해 베이스라인을 만들 수 있습니다(예: ResNet50) 우리의 요구에 맞게 조정합니다. 많은 모델에서 공통적으로 사용되는 백본이므로 ResNet50을 사용하겠습니다. 컴퓨터 비전 과제그리고 네트워크의 중앙 부분은 그대로 둘 수 있지만, 사용자의 설정에 맞추기 위해 입력층과 출력층은 변경해야 합니다.
이를 위해 첫 번째 합성곱 층의 채널 수를 BEV의 채널 수와 맞추겠습니다. 3채널 합성곱 층만으로는 서로 다른 의미 정보를 레이어별로 래스터화하기에 충분하지 않을 수 있습니다. 우리의 경우 고려해야 할 것은 둘 다 이미지 래스터와 차량의 움직임까지 포함해야 하므로 3개 채널을 초과하게 됩니다.
다음으로, 출력의 개수가 미래 예측 지평과 각 타임스텝 요소의 곱과 일치하는지 확인합시다(아래 예시에서는 XY 변위를 사용합니다). 지평이 50스텝이라면, 네트워크의 마지막 층에는 총 100개의 뉴런이 필요합니다.
본질적으로, 모델에는 이미지 래스터(3채널)와 함께 AV의 XY 움직임을 입력합니다. 모델은 AV의 예측된 XY 움직임을 출력합니다. 이미지와 함께 몇 개의 과거 스텝을 입력할지 조정할 수 있으며, 그에 따라 전체 입력은 다음과 같습니다: 3+(2*number_of_previous_steps), 여기서 3은 입력 래스터의 채널 수에서, 2는 X와 Y 위치에서 비롯됩니다. 마찬가지로 출력은 우리가 예측하고자 하는 미래 스텝의 수에 맞춰 설정할 수 있습니다: 2*number_of_future_steps
💡

PyTorch의 L5Kit 모델

import torch # 🔦from torch import nnfrom torchvision.models.resnet import resnet50# 🔦def build_model(config: Dict) -> torch.nn.Module:# load pre-trained Conv2D modelmodel = resnet50(pretrained=True)# change input channels number to match the rasterizer's outputnum_history_channels = (config["model_params"]["history_num_frames"] + 1) * 2num_in_channels = 3 + num_history_channelsmodel.conv1 = nn.Conv2d(num_in_channels,model.conv1.out_channels,kernel_size=model.conv1.kernel_size,stride=model.conv1.stride,padding=model.conv1.padding,bias=False,)# change output size to (X, Y) * number of future statesnum_targets = 2 * config["model_params"]["future_num_frames"]model.fc = nn.Linear(in_features=2048, out_features=num_targets)return model
주행 궤적 예측을 위한 자율주행차 학습 🚖
일반적인 ML 파이프라인에서 기대할 수 있는 흐름에 맞추기 위해, 우리의 학습 과정은 5단계를 포함하도록 구성하겠습니다.

- 데이터 수집 및 변환
- 데이터에 대해 EDA를 수행하여 다양한 주행 장면을 사람이 이해하기 쉬운 형태로 파악합니다
- 데이터에서 여러 개의 주행 궤적 예측 모델을 구축하고 실행하기
- 학습된 모델 평가 후보 모델 검증용 데이터셋에서
사실, 아래에서 검토할 수 있도록 우리 모델 레지스트리에 등록된 현재 최상위 모델의 세부 정보를 확인할 수 있습니다:
탭을 넘겨 보세요! 모든 실험 단계와 연결된 링크를 통해 모델의 모든 세부 정보를 확인할 수 있습니다 🤩
💡
prediction-model
Direct lineage view
더 깊이 분석하려면 주요 운영 대시보드를 탐색해 보세요!
Ray로 하드웨어 활용 극대화

딥러닝과 하이퍼파라미터 튜닝과 같은 현대 워크로드는 연산량이 많아 분산 또는 병렬 실행이 필요합니다. Ray 단일 머신용 코드를 손쉽게 병렬화할 수 있게 해 주며, 최소한의 코드 변경만으로 단일 CPU에서 멀티 코어, 멀티 GPU, 또는 멀티 노드로 확장할 수 있습니다. 즉, Ray는 가장 복잡한 워크로드도 손쉽게 스케일링할 수 있도록 도와줍니다.
Ray를 추가하는 방법은 다음과 같이 간단합니다:
import torch # 🔦import multiprocessing # 🔎from ray import trainfrom ray.air import session, Checkpoint # 💾from ray.train.torch import TorchTrainer # 🔦💨⚡️from ray.air.config import ScalingConfig# 🔦+🔎 Get all your useful hardware informationUSE_GPU = torch.cuda.is_available()NUM_GPUS = torch.cuda.device_count()NUM_CPUS = multiprocessing.cpu_count()# 🧮 Do some quick math to efficiently spread the workload to each GPUif USE_GPU:num_actors = NUM_GPUSnum_data_workers = NUM_CPUS // num_actorselse:num_data_workers = 4 if NUM_CPUS>=4 else NUM_CPUSideal_num_actors = NUM_CPUS // num_data_workersnum_actors = ideal_num_actors if ideal_num_actors else 1# 🔦 Define the details of a training rundef train_model(config):train_dataloader = load_data(config) # 🫵🏽 You implement this# ⚡️ Prepares Data for DDPtrain_dataloader = train.torch.prepare_data_loader(train_dataloader)model, criterion, optimizer = build_model(config) # 🔦+🫵🏽 and this...# ⚡️ Prepares Model for DDPmodel = train.torch.prepare_model(model)steps_before_checkpointing = config.get("steps_before_checkpointing", 100)max_epochs = config.get("max_epochs", 100)for epoch in range(max_epochs):model.train()torch.set_grad_enabled(True)metrics, model_outputs = train_model_epoch(train_dataloader,model, criterion,optimizer) # 🫵🏽 AND this!# 🪄🐝 Report your training metrics to your logger of choice# 💾 This includes the model checkpoints serialized by Rayif (step%steps_before_checkpointing==0) or (step==max_epochs-1):session.report(metrics=metrics,checkpoint=Checkpoint.from_dict(dict(epoch=epoch, model=model)))else:session.report(metrics=metrics)# 🔦💨⚡️ Ray deals with the rest of the hardware management for you SUPAFASTtrainer = TorchTrainer(train_loop_per_worker=train_model,scaling_config=ScalingConfig(num_workers=num_actors, use_gpu=USE_GPU),)
위의 코드 줄들은 다음을 수행합니다:
- 🔦+🔎 시스템에서 사용 가능한 CPU와 GPU 개수를 확인하세요. 모두 학습에 사용할 것을 전제로 합니다.
- 🧮 분산 학습을 위해 GPU와 CPU를 가장 효율적으로 분할하는 방법을 계산하세요
- 🔦 전체 모델 학습 실행을 시작할 수 있는 학습 스크립트를 작성하세요
- 🪄🐝 Ray 세션에 메트릭과 모델 체크포인트를 우리가 가장 좋아하는 ML 기록 시스템으로 보고하도록 설정할 수 있습니다(스포일러: Weights & Biases).
- 🔦💨⚡️ 만들기 ray.train TorchTrainer 최소한의 추가 코드만으로 병렬화된 속도 이점을 누리세요
가장 좋은 점은? 이 워크플로는 정말 재사용 가능하며, 그것도 아주 쉽게!
MLOps, 조기 종료, 하이퍼파라미터 최적화를 원하시나요? 시작해봅시다:
from ray import tunefrom ray.tune.tuner import Tuner # 📻♻️from ray.air.callbacks.wandb import WandbLoggerCallback # 🪄🐝from ray.tune.stopper import ExperimentPlateauStopper # 🛑from ray.tune.search.optuna import OptunaSearch # 🕵🏽project_name = "your_cool_project_name"n_search_attempts = 25# 🕵🏽 Define your hyperparameter optimization search strategy# You can define for which config values we want to search and howconfig["max_epochs"] = tune.quniform(1000, 5000, 250)optuna_search = OptunaSearch()# 📻♻️ Define details of the ray.tune job by providing:tuner = Tuner(trainer, # 🔦💨⚡️ The trainer from above...tune_config=tune.TuneConfig(metric="your_important_metric",mode="min",search_alg=optuna_search, # 🕵🏽 How we want to search.num_samples=n_search_attempts,),param_space={"train_loop_config": config # 🔦💨⚡️ ...with the config we want to pass to the trainer!},run_config=RunConfig(# 🛑 How to stop the experiment based on a provided metric.stop=ExperimentPlateauStopper("another_important_metric"),# 🪄🐝 Your ML System of Record (Tracked Experiments & Checkpoint Artifacts).callbacks=[WandbLoggerCallback(project=f"{project_name}-trials",save_checkpoints=True),]))# 🏃🏽♂️ Run the tune job with# - Distributed Training# - Hyperparameter Search# - Experiment Stopping# - MLOpsanalysis = tuner.fit()
- 🕵🏽 하이퍼파라미터 최적화를 위해 정의된 기본 제공 검색 전략 중 어느 것이든 활용할 수 있습니다 ray.tune
- 이는 우리가 탐색할 값들을, 전달되는 config 안에서 올바른 형식으로 미리 준비해 둔다고 가정합니다 ray.tune (그리고 더 정확하게 ray.train TorchTrainer)
- 📻♻️ 만들기 ray.tune Tuner 실험을 어떻게 튜닝해야 하는지, 그리고 각 실행을 어떤 상황에서 모니터링하는지에 대한 세부 정보를 제공할 것입니다
- 🔦💨⚡️ The TorchTrainer 에 제공되는 config가 제공될 것입니다 Tuner, 하이퍼파라미터가 자동으로 조정되어 ray.tune 그리고 콜백과 같은 유용한 실행 구성의 자동 관리
- 🕵🏽 하이퍼파라미터 탐색 에이전트, optuna 기본 샘플러와 함께 TPESampler 트리 구조 파르첸 추정기
- 각 실험에서 매개변수마다 TPE는 하나의 가우시안 혼합 모델(GMM)을 적합합니다 l(x) 최적 목적값과 연관된 매개변수 값 집합에 대해 하나의 GMM을, 그리고 또 다른 GMM을 g(x) 남은 매개변수 값들에 대해. 그런 다음 매개변수 값을 선택합니다 x 비율을 최대화하는 l(x)/g(x).
- 🛑 조기 종료 기준, ExperimentPlateauStopper 지표가 인내심 파라미터로 지정한 횟수보다 더 오래 정체 상태(개선 없음)에 머무르면 전체 실험을 중지합니다.
- 🪄🐝 The WandbLoggerCallback 제공한 ray.air 하나의 ML 시스템에서 실험 추적과 모델 아티팩트를 빠르게 추가하고 체계적으로 관리하기 위해 필요한 간단한 한 줄 추가입니다
- 🏃🏽♂️ 최적화된 하드웨어에서 수백 개의 최적화된 실험을 실행하는 일도 다음처럼 간단해집니다 tuner.fit()!
- 🫵🏽 반복해서 강조합니다: 최고의 장점은? 이 워크플로는 정말 재사용 가능합니다. 예를 들어 정말 쉽게.
학습 출력!
학습
Run set
56
핵심 인사이트
- 위의 평행좌표 플롯에서 대부분의 모델이 낮은 값 주변으로 집중되는 것을 확인할 수 있습니다. avg_loss. 바로 우리가 원하던 것입니다! 우리는 하이퍼파라미터 최적화 도구를 사용합니다 Optuna 시도할 하이퍼파라미터 조합을 반복적으로 선택하여 최적의 후보를 고릅니다.
- 더 낮은 학습률(0.0009 미만)과 더 많은 학습 스텝을 사용하면 평균 손실이 낮아집니다.
- 더 큰 배치 크기에 더 낮은 학습률을 조합하면 평균 손실이 낮아집니다.
- 래스터 유형(시맨틱 vs 위성)과 평균 손실 사이의 상관관계는 거의 없습니다.
평가
🦋(청록) = 학습된 모델이 예측한 자율주행차의 주행 경로
만약 🐷(분홍) = 자율주행차의 실제 주행 궤적이 🦋(청록) = 학습된 모델이 예측한 자율주행차의 주행 경로와 일치하지 않는다면, 우리 모델의 성능은 좋지 않은 것입니다.
표에 제시한 애니메이션을 보면, 실제 지도 위 현실 환경에서 우리 모델이 자율주행차의 주행을 어떻게 유도했을지 직접 확인할 수 있습니다. 우리 모델 자주 크래시 나긴 하지만… 적어도 Ray와 Weights & Biases를 쓰면 더 나은 모델을 학습시키는 코드는 안 망가질 거예요 🫰🏽
결론
학습된 모델의 결과를 보니, 솔직히 말해 이 모델은 우스울 정도로 명백한 오류들 때문에 프로덕션에 올리기 어렵겠네요 🤷🏽♂️. 그래도 Weights & Biases 덕분에 이런 오류들을 쉽게 찾아낼 수 있었을 뿐만 아니라, 팀의 모든 구성원이 남긴 인사이트와 함께 이 오류로 이어졌을 수 있는 모든 단계를 빠짐없이 기록으로 남겨두었습니다.
관련 자료
Object Detection for Autonomous Vehicles (A Step-by-Step Guide)
Digging into object detection and perception for autonomous vehicles using YOLOv5 and Weights & Biases
A System of Record for Autonomous Driving Machine Learning Models
A look at the most useful Weights & Biases features for autonomous vehicle companies
Modeling Drivable Areas for Autonomous Vehicles with Real and Synthetic Data
Autonomous vehicles need to understand where they can and can't drive. In this article, we'll dig into modeling for this use case with the help of Weights & Biases.
Lyft's High-Capacity End-to-End Camera-Lidar Fusion for 3D Detection
Learn how Lyft Level 5 combines multiple perception sensors in their self-driving automobile research
Add a comment