<?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.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>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;div class="ltag-github-readme-tag"&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;/div&gt;
&lt;/strong&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>
