Ashok Elluswamy1:13:11
Thank you, Andre. Hi everyone. My name is Ashok. I lead the planning and controls, auto-labeling, and simulation teams. So like Andre mentioned, the visual networks take dense video data and then compress it down into a 3D vector space. The role of the planner now is to consume this vector space and get the car to the destination while maximizing the safety, comfort, and the efficiency of the car. Even back in 2019, our planner was a pretty capable driver. It was able to stay in the lanes, make lane changes as necessary, and take exits off the highway. But city driving is much more complicated. Barely there are structured lane lines. Vehicles do much more free-form driving. Then the car has to respond to all of the curbs and crossing vehicles and pedestrians doing funny things. What is the key problem in planning? Number one, the action space is very non-convex, and number two, it is high-dimensional. What I mean by non-convex is there can be multiple possible solutions that can be independently good, but getting a globally consistent solution is pretty tricky. So there can be pockets of local minima that the planning can get stuck into. And secondly, the high dimensionality comes because the car needs to plan for the next 10 to 15 seconds and needs to produce the position, velocities, and acceleration for this entire window. This is a lot of parameters to produce at runtime. Discrete search methods are really great at solving non-convex problems because they are discrete, they don't get stuck in local minima, whereas continuous function optimization can easily get stuck in local minima and produce poor solutions that are not great. On the other end, for high-dimensional problems, discrete search sucks because it is discrete, it does not use any graded information, so literally has to go and explore each point to know how good it is, whereas continuous optimization uses gradient-based methods to very quickly go to a good solution. Our solution to this planning problem is to break it down hierarchically. First, use a coarse search method to crunch down the non-convexity and come up with a convex corridor, and then use continuous optimization techniques to make the final smooth trajectory. Let's see an example of how the search operates. So here we're trying to do a lane change. In this case, the car needs to do two back-to-back lane changes to make the left turn up ahead. For this, the car searches over different maneuvers. So the first one it searches is a lane change that's close by, but the car brakes pretty harshly, so it's pretty uncomfortable. The next maneuver it tries does the lane change a bit late, so it speeds up, goes beyond the other car, goes in front of the other cars, and finds it at the lane change, but now it risks missing the left turn. We do thousands of such searches in a very short time span. Because these are all physics-based models, these features are very easy to simulate, and in the end, we have a set of candidates, and we finally choose one based on the optimality conditions of safety, comfort, and easily making the turn. So now the car has chosen this path, and you can see that as the car executes this trajectory, it pretty much matches what we had planned, the cyan plot on the right side here. And that one is the actual velocity of the car, and the white line underneath it was the plan. So we are able to plan for 10 seconds here and able to match that when you see in hindsight. So this is a well-made plan. When driving alongside other agents, it's important to not just plan for ourselves, but instead we have to plan for everyone jointly and optimize for the overall scene's traffic flow. In order to do this, what we do is we literally run the Autopilot planner on every single relevant object in the scene. Here's an example of why that's necessary. This is an auto corridor. I'll let you watch the video for a second. Yeah, that was Autopilot driving an auto corridor, going around parked cars, cones, and poles. Here, there's a 3D view of the same thing. The oncoming car arrives now, and Autopilot slows down a little bit, but then realizes that we cannot yield to them because we don't have any space to our side, but the other car can yield to us instead. So instead of just blindly braking here, all of our reasoning about that car has low enough velocity that they can pull over and should yield to us because we cannot yield to them, and assertively makes progress. A second oncoming car arrives now. This vehicle has higher velocity, and like I said earlier, we literally run the Autopilot planner for the other object. So in this case, we run the planner for them. That object's plan now goes around their side's parked cars, and then after they pass the parked cars, goes back to the right side of the road for them. Since we don't know what's in the mind of the driver, we actually have multiple possible features for this car here. One feature is shown in red, the other one is shown as green. The green one is a plan that yields to us, but since this object's velocity and acceleration are pretty high, we don't think that this person is going to yield to us, and they are actually going to go around these parked cars. So Autopilot decides that, okay, I have space here, this person is definitely going to come, so I'm going to pull over. So as Autopilot is pulling over, we notice that that car has chosen to yield to us based on their yaw rate and their acceleration, and Autopilot immediately changes his mind and continues to make progress. This is why we need to plan for everyone, because otherwise we wouldn't know that this person is going to go around the other parked cars and come back to their side. If you didn't do this, Autopilot would be too timid, and it would not be a practical self-driving car. So now we saw how the search and planning for other people set up a convex valley. Finally, we do a continuous optimization to produce the final trajectory that the planner needs to take. Here, the gray thing is the convex corridor, and we initialize the spline in heading and acceleration parameterized over the arc length of the plan. And you can see that the countermeasure continuously makes fine-grained changes to reduce all of its cost. Some of the costs, for example, are distance from obstacles, traversal time, and comfort. For comfort, you can see that the lateral acceleration plots on the right have nice trapezoidal shapes. It's going to come up, yeah, here on the right side, the green plot. That's a nice trapezoidal shape, and if you record on a human trajectory, this is pretty much how it looked like. The lateral jerk is also minimized. So in summary, we do a search for both us and everyone else in the scene, we set up a convex corridor, and then optimize for a smooth path. Together, these can do some really neat things like shown above. But driving looks a bit different in other places, like where I grew up from. It's very much more unstructured. Cars and pedestrians cutting each other off, braking, honking. It's a crazy world. We can try to scale up these methods, but it's going to be really difficult to efficiently solve this at runtime. What we instead want to do is use learning-based methods to efficiently solve them. And I want to show why this is true. So we're going to go from this complicated problem to a much simpler toy parking problem, but still illustrates the core of the issue. Here, this is a parking lot. The ego car is in blue and needs to park in the green parking spot here. So it needs to go around the curbs, the parked cars, and the cones shown in orange here. Let's do this simple baseline. It's A*, the standard algorithm that uses a lattice space search, and the heuristic here is a distance, the Euclidean distance to the goal. So you can see that it directly shoots towards the goal, but very quickly gets trapped in a local minima, and it backtracks from there, and then searches a different path to try to go around this parked car. Eventually, it makes progress and gets to the goal, but ends up using 400,000 nodes for making this. Obviously, this is a terrible heuristic. We want to do better than this. So if you added a navigation route to it and had the car to follow the navigation route while being close to the goal, this is what happens. The navigation route helps immediately, but still, when it encounters cones or other obstacles, it basically does the same thing as before, backtracks, and then searches that whole new path. And the A* search has no idea that these obstacles exist. It literally has to go there, check if it's in collision, and if it's in collision, back up. The navigation heuristic helped, but still, this took 22,000 nodes. We can design more and more of these heuristics to help the search go faster and faster, but it's really tedious and hard to design a globally optimal heuristic. Even if you had a distance function from the cones that guided the search, this would only be effective for the single cone. But what we need is a global value function. So instead, what we want to use is neural networks to give this heuristic for us. The visual networks produce a vector space, and we have cars moving around in it. This basically looks like an Atari game, and it's a multiplayer version. So we can use techniques such as MuZero, AlphaZero, etc., that was used to solve Go and other Atari games to solve the same problem. So we're working on neural networks that can produce state and action distributions that can then be plugged into Monte Carlo research with various cost functions. Some of the cost functions can be explicit cost functions like distance, collisions, comfort, traversal time, etc., but they can also be interventions from the actual manual driving events. We train such a network for this simple parking problem. So here again, same problem. Let's see how MCTS research does. So here you notice that the planner is basically able to in one shot make progress towards the goal. Notice that this is not even using a navigation heuristic. Just given the scene, the planner is able to go directly towards the goal. All the other options you're seeing are possible options. It's not choosing any of them, just using the option that directly takes it towards the goal. The reason is that the neural network is able to absorb the global context of the scene and then produce a value function that effectively guides it towards the global minima as opposed to getting stuck in any local minima. So this only takes 288 nodes, and several orders of magnitude less than what was done in the A* with the Euclidean distance heuristic. So this is what a final architecture is going to look like. The vision system is going to crush down the dense video data into a vector space. It's going to be consumed by both an explicit planner and a neural network planner. In addition to this, the network planner can also consume intermediate features of the network. Together, this produces a trajectory distribution, and it can be optimized end-to-end both with explicit cost functions and human intervention and other imitation data. This then goes into explicit planning function that does whatever is easy for that and produces the final steering and acceleration commands for the car. With that, we need to now explain how we train these networks, and for training...
These networks need large data sets. And with that, I'm ready to speak briefly about manual labeling.
Yeah, so the story of data sets is critical. Of course, so far we've talked only about neural networks, but neural networks only establish an upper bound on your performance. Many of these neural networks have hundreds of millions of parameters, and these hundreds of millions of parameters have to be set correctly. If you have a bad setting of parameters, it's not going to work. So neural networks are just an upper bound; you also need massive data sets to actually train the correct algorithms inside them. Now, in particular, I mentioned we want data sets directly in the vector space. And so the question becomes, how can you accumulate, because our networks have hundreds of millions of parameters, how do you accumulate millions and millions of vector space examples that are clean and diverse to actually train these neural networks effectively?
Now, so there's a story of data sets and how they've evolved on the side of all of the models and developments that we've achieved. Now, in particular, when I joined roughly four years ago, we were working with a third party to obtain a lot of our data sets. Now, unfortunately, we found very quickly that working with a third party to get data sets for something this critical was just not going to cut it. The latency of working with a third party was extremely high, and honestly, the quality was not amazing. And so, in the spirit of full vertical integration at Tesla, we brought all of the labeling in-house. And so over time, we've grown more than a 1,000-person data labeling org that is full of professional labelers who are working very closely with the engineers. So actually, they're here in the U.S. and co-located with the engineers here in the area as well. And so we work very closely with them, and we also build all of the infrastructure for them from scratch ourselves. So we have a team we are going to meet later today that develops and maintains all of this infrastructure for data labeling. And so here, for example, I'm showing some of the screenshots of some of the latency, throughput, and quality statistics that we maintain about all of the labeling workflows and the individual people involved and all the tasks and how the numbers of labels are growing over time. So we found this to be quite critical, and we're very proud of this.
Now, in the beginning, roughly three or four years ago, most of our labeling was in image space. And so you can imagine that this is taking quite some time to annotate an image like this, and this is what it looked like, where we are sort of drawing polygons and polylines on top of these single individual images. As I mentioned, we need millions of vector space labels, so this is not going to cut it. So very quickly, we graduated to three-dimensional or four-dimensional labeling, where we are directly labeling in vector space, not in individual images. So here, what I'm showing is a clip, and you are seeing a very small reconstruction—you're about to see a lot more reconstructions soon—but it's a very small reconstruction of the ground plane on which the car drove and a little bit of the point cloud here that was reconstructed. And what you're seeing here is that the labeler is changing the labels directly in vector space, and then we are reprojecting those changes into camera images. So we're labeling directly in vector space, and this gave us a massive increase in throughput for a lot of our labels because you're labeled once in 3D and then you get to reproject. But even this, we realized, was actually not going to cut it. So because people and computers have different pros and cons, so people are extremely good at things like semantics, but computers are very good at geometry, reconstruction, triangulation, tracking. And so really, for us, it's much more becoming a story of how do humans and computers collaborate to actually create these vector space data sets. And so we're going to now talk about auto-labeling, which is some of the infrastructure we've developed for labeling these clips at scale.
Hi again. So even though we have lots of human laborers, the amount of training data needed for training with networks significantly outnumbers them. So we try to invest in a massive auto-labeling pipeline. Here's an example of how we label a single clip. A clip is an entity that has dense sensor data like videos, IMU data, GPS, odometry, etc. This can be 45 seconds to a minute long. These can be uploaded by our own engineering cars or from customer cars. We collect these clips and then send them to our servers, where we run a lot of neural networks offline to produce intermediate results like segmentation masks, depth, point matching, etc. This then goes through a lot of robotics and an algorithm to produce a final set of labels that can be used to train the networks.
One of the first tasks we want to label is the road surface. Typically, we can use splines or meshes to represent the road surface, but those are, because of the topology restrictions, not differentiable and not amenable to producing this. So what we do instead is, in the style of neural radiance fields work from last year, which is quite popular, so we use an implicit representation to represent the road surface. Here, we are querying XY points on the ground and asking for the network to predict the height of the ground surface, along with various semantics such as curves, lane boundaries, road surface, drivable space, etc. So given a single XY, we get a Z. Together, these make a 3D point, and they can be reprojected into all the camera views. So we make millions of such queries and get lots of points. These points are reprojected into all the camera views. We are showing on the top right here one such camera image with all these points reprojected. Now, we can compare this reprojected point with the image space prediction of the segmentations, and jointly optimizing this across all the camera views, across space and time, produced an excellent reconstruction. Here's an example of how that looks like. So here, this is an optimized road surface that reprojection to the eight cameras that the car has, and across all of time, and you can see how it's consistent across both space and time.
So a single car driving through some location can sweep out some patch around the trajectory using this technique. But we don't have to stop there. So here, we collected different clips from the same location, from different cars maybe, and each of them sweeps out some part of the road. The cool thing is we can bring them all together into a single giant optimization. So here, these 16 different trips are organized, using aligned using various features such as road edges, lane lines, all of them should agree with each other and also agree with all of their image space observations. Together, this produces an effective way to label the road surface, not just where the car drove but also in other locations that it hasn't driven. Again, the point of this is not to just build HD maps or anything like that; it's only to label the clips through these intersections so we don't have to maintain them forever, as long as the labels are consistent with the videos that they were collected at. Optionally, then humans can come on top of this and clean up any noise or additional metadata to make it even richer.
We don't have to stop at just the road surface; we can also arbitrarily reconstruct 3D static obstacles. Here, this is a reconstructed 3D point cloud from our cameras. The main innovation here is the density of the point cloud. Typically, these points require texture to form associations from one frame to the next frame, but here we are able to produce these points even on textureless surfaces like the road surface or walls. And this is really useful to annotate arbitrary obstacles that we can see on the scene in the world.
One more cool advantage of doing all of this on the servers offline is that we have the benefit of hindsight. This is a super useful hack because, say, in the car, then the network needs to produce the velocity, it just has to use the historical information and guess what the velocity is. But here, we can look at both the history but also the future and basically cheat and get the correct answer of the kinematics, like velocity, acceleration, etc. One more advantage is that we can have different tracks, but we can stitch them together, that even through occlusions, because we know the future, we have future tracks, we can match them and then associate them. So here, you can see the pedestrians on the other side of the road are persisted even through multiple occlusions by these cars. This is really important for the planner because the planner needs to know if it saw someone, it still needs to account for them even when they are occluded. So this is a massive advantage.
Combining everything together, we can produce these amazing data sets that annotate all of the road texture, or the static objects, and all of the moving objects even through occlusions, producing excellent kinematic labels. All you can see how the cars turn smoothly, produce really smooth labels, or the pedestrians are consistently tracked. The parked cars, obviously zero velocity, so we can also know that they are parked. So this is huge for us. This is one more example of the same thing. You can see how everything is consistent. We want to produce a million such labeled clips and train our video, multi-camera video networks with such large data set and really crush this problem. We want to get the same view that's consistent that we're seeing here in the car.
We started our first exploration of this with the remove the radar data project. We removed it in a very short time span, I think within three months. In the early days of the network, we noticed, for example, in low visibility conditions, the network can suffer, understandably, because obviously this truck just dumped a bunch of snow on us, and it's really hard to see, but we should still remember that this car was in front of us. But our networks early on did not do this because of the lack of data in such conditions. So what we did, we tasked the fleet to produce lots of similar clips, and the fleet responded. It did. So it produces lots of video clips where shit's falling out of all other vehicles. And we send this through our auto-labeling pipeline that was able to label 10k clips within a week. This would have taken several months with humans labeling every single clip here. So we did this for 200 different conditions, and we were able to very quickly create large data sets, and that's how we were able to remove this. So once we train the networks with this data, you can see that it's totally working and keeps the memory that the subject was there and provides this.
So finally, we wanted to actually get a Cybertruck into a data set for the remove radar. Can you all guess where we got this clip from? I'll give you a moment. Someone said it, yes, yes, it's rendered. It's our simulation. It was hard for me to tell initially, and if I may say so myself, it looks pretty, it looks very pretty. So yeah, in addition to auto-labeling, we also invest heavily in using simulation for labeling our data. So this is the same scene as seen before, but from a different camera angle. So a few things that I wanted to point out, for example, the ground surface, it's not a plain asphalt, there are lots of cars and cracks and tar seams. There's some patchwork done on top of it. Vehicles move realistically, the truck is articulated, even goes over the curb and makes a wide turn. The other cars behave smartly, they avoid collisions, go around cars, and also smooth and actually great smooth, brake and accelerate smoothly. The car here with the logo on the top is Autopilot, actually, Autopilot is driving that car, and it's making an unprotected left hand. And since it's a simulation, it starts from the vector space, so it has perfect labels. Here we show a few of the labels that we produce. These are vehicle cuboids with kinematics, depth, surface normals, segmentation. But Andre can name a new task that he wants next week, and we can very quickly produce this because we already have a vector space, and we can write the code to produce these labels very, very quickly.
So when does simulation help? It helps, number one, when the data is difficult to source. As large as our fleet is, it can still be hard to get some crazy scenes like this couple and their dog running on the highway while there are other high-speed cars around. This is a pretty rare scene, I'd say, but still can happen, and Autopilot still needs to handle it when it happens. When data is difficult to label, there are hundreds of pedestrians crossing the road. This could be a Manhattan downtown, people crossing the road. It's going to take several hours for humans to label this clip, and even for automatic labeling algorithms, this is really hard to get the association right, and it can produce like bad velocities. But in simulation, this is trivial because you already have the objects, you just have to spit out the cuboids and the velocities. And also, finally, when we introduce closed-loop behavior where the car needs to be in a deterministic situation or the data depends on the actions, this is pretty much the only way to get it reliably. All this is great. What's needed to make this happen? Number one, accurate sensor simulation. Again, the point of the simulation is not to just produce pretty pictures; it needs to produce what the camera in the car would see and other sensors would see. So here, we are stepping through different exposure settings of the real camera on the left side and the simulation on the right side. We're able to pretty much match what the real cameras do. In order to do this, we had to model a lot of the properties of the camera in our sensor simulation, starting from sensor noise, motion blur, optical distortions, even headlight transmissions, even like diffraction patterns of the windshield, etc. We don't use this just for the Autopilot software; we also use it to make hardware decisions such as lens design, camera design, sensor placement, even headlight transmission properties.
Second, we need to render the visuals in a realistic manner. You cannot have what in the game industry called jaggies, these are aliasing artifacts that are a dead giveaway that this is simulation. We don't want them, so we go through a lot of pains to produce a nice special temporal anti-aliasing. We also are working on neural rendering techniques to make this even more realistic. Yeah, in addition, we also use ray tracing to produce realistic lighting and global illumination. Okay, that's the last of the cop cars, I think. We obviously cannot have really just four or five cars because the network will easily overfit because it knows the sizes. So we need to have realistic assets like the moose on the road here. We have thousands of assets in our library, and they can wear different shirts and actually can move realistically. So this is really cool. We also have a lot of different locations mapped and created to create these sim environments. We have actually 2,000 miles of road built, and this is almost the length of the roadway from the east coast to the west coast of the United States, which I think is pretty cool. In addition, we have built efficient tooling to build several miles more on a single day for a single artist. But this is just the tip of the iceberg. Actually, most of the data that we use to train is created procedurally using algorithms as opposed to artists making these simulation scenarios. So these are all procedurally created roads with lots of parameters such as curvature, various varying trees, cones, poles, cars with different velocities, and the interaction produces an endless stream of data for the network. But a lot of this data can be boring because the network might already get it correct. So what we do is we use also ML-based techniques to basically poke the network to see where it's failing at and create more data around the failure points of the network. So this is in closed-loop, trying to make the network performance be better.
We don't want to stop there. So actually, we want to recreate any failures that happen to the Autopilot in simulation so that we can hold Autopilot to the same bar from then on. So here, on the left side, you are seeing a real clip that was collected from a car. It then goes through our auto-labeling pipeline to produce a 3D reconstruction of the scene along with all the moving objects. With this, combined with the original visual information, we recreate the same scene synthetically and create a simulation scenario entirely out of it. So, and then when we replay Autopilot on it, Autopilot can do entirely new things, and we can form new worlds, new outcomes from the original failure. This is amazing because we really don't want Autopilot to fail, and when it fails, we want to capture it and keep it to that bar. Not just that, we can actually take the same approach that we said earlier and take it one step further. We can use neural rendering techniques to make it look even more realistic. So we take the original video clip, we create a synthetic simulation from it, and then apply neural rendering techniques on top of it, and it produces this, which looks amazing in my opinion, because this one is very realistic and looks almost like it was captured by the actual cameras. They saw results from last night because it was cool and we wanted to present it. But yeah, yeah, I'm very excited for what sim can achieve. But this is not all because networks trained in the car already use simulation data. We used 300 million images with almost half a billion labels, and we want to crush down all the tasks that are going to come up for the next several months. With that, I invite Milan to explain how we scale these operations and really build a label factory and spit out millions of labels.