Os veículos autônomos precisam ver o mundo rapidamente e com precisão. Mas a percepção em tempo real é difícil quando seu modelo está se afogando em milhões de pontos LiDAR e imagens de alta resolução. A solução? Fusão de sensores, quantização do modelo e uma pitada de aceleração de tensort.
Deixe -me orientá -lo como otimizei um Modelo de percepção multimodal Para correr 40% mais rápido, mantendo -o nítido o suficiente para evitar pedestres e carros estacionados.
O gargalo: um milhão de pontos, um milhão de problemas
Veículos autônomos confiam Lidar e câmerascada um com pontos fortes e fracos. Lidar se destaca em estimativa de profundidademas cospe milhões de pontos por segundo. Câmeras fornecem Texturas e cores ricas mas não tem profundidade. Fuir ambos em um único pipeline significa equilibrar velocidade e precisão.
Problema 1: o atraso entre os dados do Lidar e da câmera
Quando o LiDAR termina a digitalização, a câmera já capturou um novo quadro. Esse desalinhamento significa que as posições do objeto não correspondem.
Consertar: Eu usei compensação de movimento do ego com Filtros de Kalman Para ajustar os pontos do Lidar dinamicamente. Aqui está um trecho de como funciona em Python:
import numpy as np
class EgoMotionCompensation:
def __init__(self, initial_pose, process_noise, measurement_noise):
self.state = initial_pose
self.P = np.eye(5) * 0.01
self.Q = np.diag(process_noise)
self.R = np.diag(measurement_noise)
def predict(self, dt):
# Unpack state
x, y, yaw, vx, vy = self.state
x_pred = x + vx * dt
y_pred = y + vy * dt
yaw_pred = yaw
self.state = np.array([x_pred, y_pred, yaw_pred, vx, vy])
F = np.eye(5)
F[0, 3] = dt
F[1, 4] = dt
self.P = F @ self.P @ F.T + self.Q
def update(self, measurement):
#measurement = [x_meas, y_meas, yaw_meas]
H = np.array([
[1, 0, 0, 0, 0],
[0, 1, 0, 0, 0],
[0, 0, 1, 0, 0]
])
z = np.array(measurement)
y_err = z - H @ self.state
S = H @ self.P @ H.T + self.R
K = self.P @ H.T @ np.linalg.inv(S)
self.state += K @ y_err
I = np.eye(5)
self.P = (I - K @ H) @ self.P
def apply_correction(self, lidar_points, dt):
#predict and update using IMU/odometry
self.predict(dt)
#Suppose we have a measurement from the IMU or odometry
#assume partial measurement [x_meas, y_meas, yaw_meas]
measurement = [self.state[0], self.state[1], self.state[2]]
self.update(measurement)
x, y, yaw, _, _ = self.state
cos_yaw, sin_yaw = np.cos(yaw), np.sin(yaw)
transformed = []
for px, py, pz in lidar_points:
#rotate and translate
x_new = (px * cos_yaw - py * sin_yaw) + x
y_new = (px * sin_yaw + py * cos_yaw) + y
transformed.append((x_new, y_new, pz))
return np.array(transformed)
Este ajuste desalinhamento reduzido em 85%aumentando a precisão da detecção de objetos.
Problema 2: Fusão do sensor: fazendo lidar e câmeras jogarem bem
Agora que corrigimos o intervalo de tempo, temos outro problema: Lidar dá nuvens pontuaisenquanto as câmeras fornecem Imagens RGB. Precisávamos de um representação única para ambos.
Nós construímos um Modelo de vista para os olhos do pássaro (BEV) que projetos Lidar aponta no plano da imagem e alinhe -os com pixels da câmera.
Como fizemos isso:
- LiDAR e câmera calibrados com matrizes intrínsecas e extrínsecas.
- Pontos Lidar projetados no espaço da imagem.
- Recursos fundidos Usando um transformador de atendimento cruzado.
Veja como a projeção funciona em Python:
import torch
import torch.nn.functional as F
import cv2
import numpy as np
def voxelize_points(lidar_points, voxel_size=(0.1, 0.1, 0.2)):
#Transform LiDAR points into 3D voxel indices
coords = np.floor(lidar_points / np.array(voxel_size)).astype(int)
coords -= coords.min(0)
voxels = np.zeros((coords[:,0].max()+1, coords[:,1].max()+1, coords[:,2].max()+1))
for (x_idx, y_idx, z_idx) in coords:
voxels[x_idx, y_idx, z_idx] += 1
return voxels
def project_voxel_to_image(voxel_coords, camera_matrix, rvec, tvec, voxel_size):
"""
Projects 3D voxel centers into image space using a known camera matrix (including distortion).
"""
#compute center for each voxel
voxel_centers = []
for (x_idx, y_idx, z_idx) in voxel_coords:
center_x = x_idx * voxel_size[0]
center_y = y_idx * voxel_size[1]
center_z = z_idx * voxel_size[2]
voxel_centers.append([center_x, center_y, center_z])
voxel_centers = np.array(voxel_centers, dtype=np.float32).reshape(-1, 1, 3)
#project to image plane
img_pts, _ = cv2.projectPoints(voxel_centers, rvec, tvec, camera_matrix, None)
return img_pts
def fuse_features(camera_features, lidar_features):
"""
cross-attention: queries come from camera_features,
keys/values from lidar_features, to refine camera representation
based on 3D data.
"""
#camera_features, lidar_features are [Batch, Channels, Height, Width]
fused = torch.cat([camera_features, lidar_features], dim=1)
fused = F.relu(F.conv2d(fused, torch.randn(128, fused.size(1), 3, 3)))
return fused
Esse Detecção melhorada em 29%ajudando o modelo a entender melhor seu ambiente.
Cortando o tempo de inferência em 40% com tensorrt e quantização
Mesmo com melhor fusão, o tempo de inferência estava nos matando. A execução de modelos de aprendizado profundo em hardware incorporado não é o mesmo que as GPUs em nuvem. Nós precisávamos encolher o modelo sem perder a precisão.
A solução: Tensorrt + quantização
-
Pytorch convertido em tensorrt: Tensorrt otimiza gráficos de computação, funde camadas e reduz a sobrecarga da memória.
-
Quantização INT8 aplicada: Este ponto flutuante de 32 bits comprimido em Representações de 8 bits fazendo cálculos 4x mais rápido.
Técnica de quantização que foi usada:
import torch
from torch.ao.quantization import (
get_default_qconfig_mapping,
prepare_fx,
convert_fx
)
def apply_quantization(model, calibration_data):
model.eval()
#Use a QConfigMapping that sets INT8 or mixed precision
qconfig_mapping = get_default_qconfig_mapping("fbgemm")
example_inputs = (calibration_data[0].unsqueeze(0), calibration_data[1].unsqueeze(0))
prepared_model = prepare_fx(model, qconfig_mapping, example_inputs)
#Run calibration
with torch.no_grad():
for data in calibration_data:
fused_input = data[0].unsqueeze(0), data[1].unsqueeze(0)
prepared_model(*fused_input)
quantized_model = convert_fx(prepared_model)
return quantized_model
Um exemplo de como eu converti o modelo Pytorch:
import tensorrt as trt
import os
def build_tensorrt_engine(onnx_file_path, precision="int8", max_batch_size=4, input_shape=(3, 256, 256)):
trt_logger = trt.Logger(trt.Logger.INFO)
builder = trt.Builder(trt_logger)
network_flags = 1 << int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH)
network = builder.create_network(flags=network_flags)
parser = trt.OnnxParser(network, trt_logger)
if not os.path.exists(onnx_file_path):
raise FileNotFoundError(f"ONNX file not found: {onnx_file_path}")
with open(onnx_file_path, "rb") as f:
if not parser.parse(f.read()):
for i in range(parser.num_errors):
print(parser.get_error(i))
raise ValueError("Failed to parse the ONNX file.")
config = builder.create_builder_config()
if precision == "int8":
config.set_flag(trt.BuilderFlag.INT8)
elif precision == "fp16":
config.set_flag(trt.BuilderFlag.FP16)
profile = builder.create_optimization_profile()
#define min/opt/max batch sizes
min_shape = (1,) + input_shape
opt_shape = (max_batch_size // 2,) + input_shape
max_shape = (max_batch_size,) + input_shape
input_name = network.get_input(0).name
profile.set_shape(input_name, min_shape, opt_shape, max_shape)
config.add_optimization_profile(profile)
engine = builder.build_engine(network, config)
return engine
Resultados:
- O tempo de inferência caiu de 250ms → 75ms por quadro.
- A pegada de memória reduzida em 40%.
- O desempenho em tempo real melhorou para 5 qps.
Próximas etapas: aprendizado de ponta a ponta
Ainda estamos explorando Modelos de ponta a pontaonde Percepção e planejamento acontecem em um pipeline de aprendizado profundo. A ideia? Em vez de vários módulos para Detecção de objetos, estimativa de faixa e planejamento de caminhosdeixamos uma rede neural Aprenda tudo do zero.
Alguns resultados iniciais mostram promessa, mas O treinamento precisa de conjuntos de dados enormes e Interpretabilidade é um desafio. Ainda assim, estamos avançando para Navegação totalmente orientada pela IA.
Pensamentos finais: ai que vê e pensa rápido
Misturando Fusão de sensores, correção de movimento do ego e aceleração da tensorrtfizemos a IA autônoma Mais rápido e mais inteligente.
O próximo passo? Escalando -o além da pesquisa e Obtendo na estrada. Se você está trabalhando nos modelos AV, vamos conectar, eu adoraria saber como você está enfrentando desafios de velocidade de inferência e percepção.