So hello, welcome new people. My name is George Hots. I am working on a deep learning library called Tiny Grad. So you can get Tiny Grad on GitHub on your friendly neighborhood GitHub. And this is Tiny Grad. It has 22,000 stars, so it can't be too bad. Think about it like PyTorch. It's very similar to PyTorch. Maybe the best example to start with is this example called Beautiful MNIST. So Beautiful MNIST, this is an MNIST example. And unlike a lot of MNIST examples, it gets you 98%. So we can go over here to my Mac, and we can actually run it. So let's just update the latest master. And then let's give it a try. Examples of Beautiful MNIST. So it's actually pretty fast. It's training an MNIST model now. And it got 97.69%. You're like, oh, this is a boring, oh, we'll let the non-substalk. We'll let the non-substalk. That's a good point. We'll let the non-substalk. So this is Tiny Grad. Tiny Grad is my deep learning library. It's actually a company. We are the TinyCorp, the TinyGrad.org. We have, and we have two people working full time at the TinyCorp. We have some interns that we're very excited about starting soon. So yeah. So you're like, oh, well, why would you use this instead of PyTorch, right? And PyTorch is actually good software. Unlike self-driving cars where everyone else is an idiot, PyTorch is actually pretty good software. Jax is pretty good software. What are the differences between TinyGrad and the other frameworks? The whole difference is this. These are the only operations that TinyGrad compiles to. So we have unary ops, binary ops, and turnary ops. Those are all examples of element-wise ops. We have reduce ops, which can reduce an axis like a somewhere in Max. We have buffer ops, which deal with actual physical buffers on the device. We have movement ops, which deal with different ways to look at buffers. And then we have load ops. And load ops are just like contiguous copy, very boring things. So the only thing that really exists is element-wise ops, reduce ops, and movement ops. And you're like, but George, how do you get a convolution? How do you get a matrix multiplication? Ha! I'll show you how you get a matrix multiplication. So this is TinyGrad's map wall right here. And we go right. And it's not that fast. Right there, you're only getting 2.4, but it's a small matrix. If you make it a big matrix, it will be a lot faster. But that's still 2.4, tariff locks, which are pretty good. So how does this work? Well, look at this code. One way to think about a matrix multiply is to think about your two matrices that you're multiplying, putting them squares on faces of a cube, doing the N cubed to multiply, and then doing an N cubed sum. And the last face of the cube is your multiplied matrix. In TinyGrad, you can actually write it like that. So you re-shape and multiply it together. And then it's broadcasted to be the cube. And then we sum across this axis of the cube. And we are left with a matrix multiply. You can also do convolutions like this. So if we go in TensorFlow.py, which is the front end for TinyGrad, we can go check out the conv code. So there is Winigrad in the conv code here. This is Winigrad. But if you don't want to use Winigrad, this is the convolution. It's very simple. It's really just a bunch of movement tops. I think it's pretty good to look at this one called pool. It's kind of confusing to read. But when you understand what it's doing, you realize that you can express convolutions, matrix multiplies, all in terms of these absolute minimum set of operations. Element-wise ops. Reduce ops and movement ops. So that is kind of the power of TinyGrad. Whereas PyTorch will have a conv2D transpose on CUDA in Uint-8. And have a specific set of code to implement that. The problem with that is you have your operations multiplied by your runtimes, multiplied by your D-types. Because of those multiplies, the amount of code you have to maintain is huge. In TinyGrad, we factorize those concepts pretty well. So the amount of code you have to maintain, you replace those multiplies with plus. We have code that implements D-types. And our code that implements D-types is completely independent of our code that implements convolutions. If you add another D-type here, this D-type will work for all convolutions, all matrix multiplies, all max pools, all everything. Then you say, how do we actually make it fast? Well, we believe in the bit of a lesson. So we have a search machine here, which does a beam search. To search over a bunch of permutations, you can do on a kernel. And the permutations are defined right here. All these different operations you can do to mess with the kernels, to keep the compute the same, but to make it actually fast. So where are we right now in practice? TinyGrad is faster than PyTorch, stable diffusion on Mac. For a bunch of things, we're the fastest on AMD. We're less competitive on Nvidia, but only because the world has put tons and tons and tons of effort into Nvidia. We're working on getting there. And that's kind of where we are right now. Something else that's really cool about TinyGrad. You can pass in this argument debug equals two, and it will show you the real kernels that it's launching to the GPU. So you can see these kernels are batched because we're using the graph API on metal. But these are the actual kernels. We have a cool argument here called GIT Graph equals one. And that will graph whatever we put in TinyGrad's GIT. And then I can go over here to net.svg. And we can actually see what this looks like. So this is the MNIST kernel. Sorry, well, this is the MNIST net. Expressing its simplest things. So like you can see, this sum is actually a convolution after some matrix ups. And does these, then it does the backwards pass. And then you'll see that this, these are backwards passes. And then this big shit here is the atom optimizer. Can you add convolution as a custom op? So you don't need that. Why do you think the convolutions in here are very fast? The convolution is automatically generated from movement ops and reduce ops. So that is what TinyGrad is. And my belief is that eventually we will pass all the other deep learning libraries because of this. As they start to collapse under the weight of their own complexity because they have multiplies in there, we have ads. So that's a different algorithmic order of complexity. We end up winning. Deep learning. Okay.