<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Devansh Bajaj</title>
    <description>The latest articles on DEV Community by Devansh Bajaj (@shinigamiflanker0208).</description>
    <link>https://dev.to/shinigamiflanker0208</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3958633%2F95657530-b15e-47d1-9d36-fed1752bc3db.png</url>
      <title>DEV Community: Devansh Bajaj</title>
      <link>https://dev.to/shinigamiflanker0208</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shinigamiflanker0208"/>
    <language>en</language>
    <item>
      <title>PyTorch vs. JAX: The Skier and the Highway (Understanding Execution Paradigms)</title>
      <dc:creator>Devansh Bajaj</dc:creator>
      <pubDate>Sat, 20 Jun 2026 11:41:44 +0000</pubDate>
      <link>https://dev.to/shinigamiflanker0208/pytorch-vs-jax-the-skier-and-the-highway-understanding-execution-paradigms-5alk</link>
      <guid>https://dev.to/shinigamiflanker0208/pytorch-vs-jax-the-skier-and-the-highway-understanding-execution-paradigms-5alk</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk3y0y4qs3m08lsrgc23n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk3y0y4qs3m08lsrgc23n.png" alt=" " width="800" height="355"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkh5uy3hu9jxyniyfdn9t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkh5uy3hu9jxyniyfdn9t.png" alt=" " width="799" height="248"&gt;&lt;/a&gt;If you skip the standard video tutorials and dive straight into the source code to build neural networks from the ground up, you quickly realize a fundamental truth: PyTorch and JAX are not just different syntax libraries. They represent entirely opposite philosophies on how to talk to a GPU.&lt;/p&gt;

&lt;p&gt;One is an object-oriented tape recorder. The other is a functional compiler.&lt;/p&gt;

&lt;p&gt;To really understand Eager Execution versus XLA Compilation, forget the math for a second and look at the shape of the computation graph. Think of it as The Skier versus The Highway.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;PyTorch: The Skier (Define-by-Run)&lt;/strong&gt; (img 1)
&lt;/h3&gt;

&lt;p&gt;PyTorch relies on dynamic eager execution. When you run a forward pass, PyTorch acts like a tape recorder, logging your mathematical operations instantly as Python executes them.&lt;/p&gt;

&lt;p&gt;The Analogy: You are a skier carving down a mountain, but you are building the trail exactly where your skis touch the snow. If your data triggers a Python if statement or a for loop midway through the network, PyTorch doesn't care—it just dynamically draws a new path to the left. You have absolute freedom to change routes mid-flight based on real-time conditions.&lt;/p&gt;

&lt;p&gt;The Bottleneck: Because you demand the freedom to alter the graph dynamically, you are forced to carry the Python interpreter on your back. It has to shout directions to the GPU at every single turn. That constant Python-to-GPU communication creates an overhead bottleneck.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;JAX: The Highway (Define-and-Run)&lt;/strong&gt; (img 2)
&lt;/h3&gt;

&lt;p&gt;JAX strips away statefulness. It demands pure, functional Python code because it doesn't build graphs on the fly. It uses a tracer.&lt;/p&gt;

&lt;p&gt;The Analogy: When you call jax.grad, JAX drives down your route once with a dummy "tracer" vehicle. It maps every tensor shape, memory allocation, and mathematical step into an intermediate static graph. Then, it hands that map to XLA (Accelerated Linear Algebra). XLA acts as a paving crew. It fuses separate operations together into a massive, straight autobahn.&lt;/p&gt;

&lt;p&gt;When your actual data flows through, there are no traffic lights, no dynamic intersections, and absolutely zero Python interpreter overhead. The hardware just executes a single, highly optimized binary block.&lt;/p&gt;

&lt;p&gt;The Bottleneck: The tracer absolutely hates standard Python control flow. If you put a standard if condition: inside a JAX function, the compiler crashes because it doesn't know which branch to bake into the static highway.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Verdict: Which to Choose?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Framework selection at the highest engineering tiers isn't about API preference; it's about the shape of your computation.&lt;/p&gt;

&lt;p&gt;Choose PyTorch if you are prototyping highly dynamic systems. If you are building Agentic AI routing, complex data-dependent loops, or architectures where the graph changes unpredictably, you need the flexibility of the skier.&lt;/p&gt;

&lt;p&gt;Choose JAX if your architecture is static. If you are building a massive Transformer model where the data flows through the exact same matrix multiplications every single iteration, XLA compilation will maximize your hardware utilization.&lt;/p&gt;

&lt;p&gt;Stop fighting the frameworks. Understand how they compile, and pick the right tool for the terrain.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>From NumPy to JAX: My First "Aha!" Moments with Accelerated AI</title>
      <dc:creator>Devansh Bajaj</dc:creator>
      <pubDate>Sat, 30 May 2026 07:39:12 +0000</pubDate>
      <link>https://dev.to/shinigamiflanker0208/from-numpy-to-jax-my-first-aha-moments-with-accelerated-ai-n2n</link>
      <guid>https://dev.to/shinigamiflanker0208/from-numpy-to-jax-my-first-aha-moments-with-accelerated-ai-n2n</guid>
      <description>&lt;p&gt;Building open-source solutions for my 100 Days of AI Agents challenge meant I needed to start looking at frameworks that scale better than standard NumPy and PyTorch. That inevitably led me to JAX.&lt;/p&gt;

&lt;p&gt;Transitioning to JAX requires a bit of a paradigm shift. If you are used to the standard Python data science stack, JAX forces you to rewire how you think about array operations, memory, and hardware execution.&lt;/p&gt;

&lt;p&gt;I spent today digging into the core mechanics, and I want to share my top 3 takeaways and the exact code snippets that made it click for me.&lt;/p&gt;

&lt;h1&gt;
  
  
  1. Immutability is a Feature, Not a Bug
&lt;/h1&gt;

&lt;p&gt;This was my first major roadblock. In standard NumPy, if you want to change an element in an array, you just reassign it in place.&lt;/p&gt;

&lt;h3&gt;
  
  
  Python
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;import numpy as np&lt;br&gt;
x = np.arange(10)&lt;br&gt;
x[0] = 10&lt;br&gt;
print(x) # Output: [10  1  2  3  4  5  6  7  8  9]&lt;br&gt;
If you try the exact same thing in JAX, it screams at you: TypeError: JAX arrays are immutable.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;JAX arrays (jax.Array) cannot be changed once created. This is a core design principle that enables JAX's functional programming nature and automatic differentiation. To update an array, JAX provides an indexed update syntax that returns an updated copy:&lt;/p&gt;

&lt;h3&gt;
  
  
  Python
&lt;/h3&gt;

&lt;p&gt;**import jax.numpy as jnp&lt;br&gt;
x = jnp.arange(10)&lt;br&gt;
y = x.at[0].set(10)&lt;/p&gt;

&lt;p&gt;print(y) # Output: [10 1 2 3 4 5 6 7 8 9]&lt;br&gt;
print(x) # Output: &lt;a href="https://dev.toOriginal%20is%20unchanged"&gt;0 1 2 3 4 5 6 7 8 9&lt;/a&gt;.**&lt;/p&gt;

&lt;p&gt;The Catch: This does create memory overhead since you are creating copies, but it completely eliminates the side-effects that make distributed computing a nightmare.&lt;/p&gt;

&lt;h1&gt;
  
  
  2. Native Hardware Awareness &amp;amp; Sharding
&lt;/h1&gt;

&lt;p&gt;JAX arrays inherently know where they live. You don't have to jump through hoops to figure out if your data is on the CPU, GPU, or TPU.&lt;/p&gt;

&lt;p&gt;By default, JAX pushes operations to the fastest available accelerator. Running this locally on my MSI Raider, I can easily inspect exactly where my array is stored using .devices():&lt;/p&gt;

&lt;h3&gt;
  
  
  Python
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;x.devices()&lt;/strong&gt; &lt;/p&gt;

&lt;h4&gt;
  
  
  Output: {CpuDevice(id=0)}
&lt;/h4&gt;

&lt;p&gt;More importantly, JAX arrays can be sharded across multiple devices for parallel execution. You can inspect this via the .sharding attribute:&lt;/p&gt;

&lt;h3&gt;
  
  
  Python
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;x.sharding&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;** Output: SingleDeviceSharding(device=CpuDevice(id=0), memory_kind=device)**&lt;/p&gt;

&lt;p&gt;It feels built from the ground up for modern hardware scaling.&lt;/p&gt;

&lt;h1&gt;
  
  
  3. The Magic of JIT Compilation
&lt;/h1&gt;

&lt;p&gt;By default, JAX executes operations one at a time, in sequence (just like standard Python). But if you wrap a function with Just-In-Time (jax.jit) compilation, JAX optimizes the entire sequence of operations and runs them all at once.&lt;/p&gt;

&lt;p&gt;I wrote a simple normalization function to test this:&lt;/p&gt;

&lt;h3&gt;
  
  
  Python
&lt;/h3&gt;

&lt;p&gt;**from jax import jit&lt;br&gt;
import jax.numpy as jnp&lt;br&gt;
import numpy as np&lt;/p&gt;

&lt;p&gt;def norm(X):&lt;br&gt;
    X = X - X.mean(0)&lt;br&gt;
    return X / X.std(0)&lt;/p&gt;

&lt;p&gt;norm_compiled = jit(norm)&lt;br&gt;
**&lt;/p&gt;

&lt;h2&gt;
  
  
  Generate some dummy data
&lt;/h2&gt;

&lt;p&gt;**np.random.seed(22)&lt;br&gt;
X = jnp.array(np.random.rand(100000, 10))&lt;br&gt;
I benchmarked both functions using %timeit (adding .block_until_ready() to account for JAX's asynchronous dispatch). The results were immediate:&lt;/p&gt;

&lt;p&gt;Standard Execution: 1.52 ms ± 16.3 μs per loop&lt;/p&gt;

&lt;p&gt;JIT Execution: 1.16 ms ± 26.2 μs per loop**&lt;/p&gt;

&lt;p&gt;Because the compiler knows the exact blueprint of the execution beforehand, it speeds things up significantly. The only limitation? Not all JAX code can be JIT compiled—it requires array shapes to be static and known at compile time.&lt;/p&gt;

&lt;p&gt;What's Next?&lt;br&gt;
This is just scratching the surface. My next deep dive is going to cover functional randomness (jax.random), automatic differentiation (jax.grad), and automatic vectorization (jax.vmap).&lt;/p&gt;

&lt;p&gt;Has anyone else here made the jump to JAX recently? What was your biggest learning curve? Drop a comment below!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;&lt;div class="ltag-github-readme-tag"&gt;&lt;strong&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;a href="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;&lt;/a&gt;
      &lt;a href="https://github.com/ShinigamiFlanker0208" rel="noopener noreferrer"&gt;
        ShinigamiFlanker0208
      &lt;/a&gt; / &lt;a href="https://github.com/ShinigamiFlanker0208/JAX" rel="noopener noreferrer"&gt;
        JAX
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/strong&gt;&lt;/div&gt;&lt;strong&gt;
&lt;/strong&gt;&lt;p&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>python</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Defeating the Whiteboard Dead-End: How I Built FlowGenix</title>
      <dc:creator>Devansh Bajaj</dc:creator>
      <pubDate>Fri, 29 May 2026 14:43:12 +0000</pubDate>
      <link>https://dev.to/shinigamiflanker0208/defeating-the-whiteboard-dead-end-how-i-built-flowgenix-4dh5</link>
      <guid>https://dev.to/shinigamiflanker0208/defeating-the-whiteboard-dead-end-how-i-built-flowgenix-4dh5</guid>
      <description>&lt;p&gt;The "&lt;strong&gt;tax on creativity&lt;/strong&gt;" is a real problem for developers and students alike. We all know the feeling: you finish a massive brainstorming session, the whiteboard is covered in brilliant system designs, and you snap a quick photo before erasing it.&lt;/p&gt;

&lt;p&gt;The problem? That photo usually becomes a digital dead-end. It sits in your gallery—static, unstructured, and impossible to interact with.&lt;/p&gt;

&lt;p&gt;That is exactly why I built FlowGenix—an AI-Powered Whiteboard to Digital Canvas Platform. I wanted to build a tool capable of transforming those ephemeral whiteboard photos into structured, completely digital assets.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The System Architecture &amp;amp; AI Foundation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Building FlowGenix required much more than just slapping an OCR wrapper onto an image. &lt;/p&gt;

&lt;p&gt;As a Software Engineer focused on Generative AI and scalable system architecture, I needed to ensure the AI could actually understand the spatial relationships of what was drawn.  &lt;/p&gt;

&lt;p&gt;I broke the core development down into two main technical pillars:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.The Intelligent Ingestion Pipeline:&lt;/strong&gt; &lt;br&gt;
I architected an end-to-end pipeline that leverages the Google Vision model. Instead of just reading text, this pipeline accurately identifies handwriting and extracts precise spatial bounding boxes from the raw image.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2.The Context-Aware Reasoning Engine:&lt;/strong&gt;&lt;br&gt;
Raw bounding boxes aren't useful without logic. To bridge this gap, I developed a context-aware reasoning engine. This engine takes the unstructured spatial inputs from the Vision model and maps them into a systematic, spatially arranged knowledge graph. It intelligently connects the nodes and edges so that the final digital output perfectly reflects the original paper or whiteboard layout.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Outcome&lt;/strong&gt;&lt;br&gt;
Turning unstructured ideas into a clean, digital canvas was an intense technical grind, but delivering high-performance, user-centric solutions is what I am passionate about.  &lt;/p&gt;

&lt;p&gt;The architecture proved its worth when FlowGenix won 1st Place at IBM Day, taking top honors for both the project's presentation and its underlying technical architecture. &lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>showdev</category>
      <category>systemdesign</category>
    </item>
  </channel>
</rss>
