ResNet Implementation
- 7 Devlogs
- 9 Total hours
An Image Classifier using the ResNet18 architecture.
An Image Classifier using the ResNet18 architecture.
After debugging for a week. It’s finally done. There’s a whole story behind this though.
To ship my project I had to create an exe file out of my project, and for that I used pyinstaller. Ran into multiple micro-dependencies issues like groovy and safehttpx. And the exe file was over 6 GBs
To reduce the exe file size, I had to use the cpu only torch packages. But when pyinstaller bundled those, I ran into some dependency issue by c10.dll file. And no matter how many workarounds and things I tried I just couldn’t fix it. I just knew at that moment that this is just not the way. There were also some issues regarding Intel OpenMP thread collision, I don’t even know what that means! :(
Researching a bit I stumbled upon onnx runtime engine for pytorch models. So, I created another app script this time with onnx model loading and numpy based preprocessing (sadly I couldn’t even use the preprocessing pipeline from pytorch). But this was simply the beginning….
When I tried building the onnx based app, the first issue was a silent failure, no log, no warning just exe file not running at all… It was some silent C level crash that python couldn’t detect, so I changed my app script again and added fault_handler. There was a raw memory collision between gradio and onnx for dll space. I changed the import order for onnx first but pyinstaller still hooked up onnx runtime dll’s to some third party package’s dll files.
Finally after that, I manually wrote a hook script and grabbed the dll files manually myself to inject into pyinstaller analysis object.
Devlog 1.5
Devlog 1.4
Devlog 1.3
Devlog 1.2
I mainly focused on profiling the model’s performance, and I found the model’s inference to be taking ~200 ms on GTX 1650. But I compiled the model with torch.compile() which basically fuses all the cuda operations in one big monolithic kernel and my jaw dropped seeing 20x performance boost taking only ~8 ms.
Oh and I also profiled the compiled model wrong the first time and also recorded the lazy jit compilation of the model during the first pass. The solution of it was to synchronise cuda with CPU and then run the profiler.
(This took wayyy more than just 31 mins, I had to install and set up WSL to run torch.compile because pytorch’s backend uses triton which doesn’t support windows).
DevLog 1.1
First off, I needed to understand how ResNet worked so I read the paper: https://arxiv.org/abs/1512.03385
After reading made a plan and visual to follow and implement in the code, starting off simple I choose to implement ResNet-18.
In code: