Abinav R Machine Learning operations MLOps, Computer Vision, Medical Imaging https://abinavravi.github.io/ Thu, 19 Mar 2026 19:43:50 +0000 Thu, 19 Mar 2026 19:43:50 +0000 Jekyll v3.10.0 Designing for 429: Why LLM Rate Limits Are a Systems Problem? <h1 id="introduction">Introduction</h1> <p>LLM adoption has reached a critical inflection point in the enterprise. While the majority of organizations rely on managed API providers to accelerate time-to-market, transitioning from experimental prototypes to business-critical production systems reveals a significant hurdle: upstream throughput constraints.</p> <p>Managed LLM APIs abstract away infrastructure complexity but introduce a “black box” variable—rate limits. When multiple distributed services, background workers, and real-time user requests compete for a shared upstream quota, rate limiting ceases to be a simple client-side error and becomes a core systems-design constraint.</p> <p>In this post we try and propose some solutions to the rate limiting problem when interacting with LLM providers.</p> <h1 id="problem-statement">Problem Statement</h1> <p>LLM providers typically enforce multi-dimensional limits to maintain multi-tenant stability. These are usually defined by:</p> <ul> <li>RPM (Requests Per Minute): Limits the frequency of orchestrating calls.</li> <li>TPM (Tokens Per Minute): Limits the actual “compute” or payload volume.</li> <li>Concurrency: Limits the number of active HTTP connections.</li> </ul> <p>These limits are generally existing to provide fair and consistent service to all their customers and ensure service stability.</p> <p>A sample LLM Application functions something like this</p> <p><img src="../assets/429_1.png" alt="" /></p> <p>In a naive architecture, scaling traffic simply increases the probability of breaching these thresholds. Without sophisticated backpressure mechanisms, a burst in traffic doesn’t just slow the system down—it triggers a cascade of failures that can compromise the user experience and system reliability. The challenge is not handling individual failures but ensuring that the whole system remains resilient</p> <p>Let us see few patterns which can help ensure the resiliency</p> <h2 id="pattern-1-exponential-backoff">Pattern 1: Exponential Backoff</h2> <p>Exponential backoff is the simplest of resilient patterns to handle rate limiting, By rate limiting what the server is telling us is we cannot get any responses right now as we have exhausted the quota by a burst of traffic, So instead of constantly hitting the servers and asking it to serve we add a retry but in exponential time. That is the client waits for a progressively longer period after each subsequent failure.</p> <p><img src="../assets/429_2.png" alt="Exponential Backoff" /></p> <p>However, Standard backoff is insufficient for distributed systems. If ten workers hit a rate limit simultaneously and retry on the same schedule, they create “thundering herd” spikes that re-congest the API. Introduce Jitter (randomized delay). This desynchronizes retries, smoothing out the request distribution and increasing the likelihood of hitting an open window in the provider’s bucket.</p> <h2 id="pattern-2-multi-model-fallback">Pattern 2: Multi Model Fallback</h2> <p>This is also quite simple to implement, Instead of just requesting one model which has limits have multiple LLM models from the same provider or different providers, for example if we are choosing claude-opus model and it is responding with 429 Too Many Requests, We should consider requesting a different model for example a Sonnet or Haiku Model or even a lower generation Opus model.</p> <p><img src="../assets/429_3.png" alt="" /></p> <p>The advantage to such a chage is that traffic is now distributed across models if one model is congested. While it maintains availability, it introduces output variance. A prompt optimized for a flagship model may produce hallucinations or formatting errors when executed on a smaller, faster model.</p> <h2 id="pattern-3-multi-model-fallback-with-appropriate-prompts">Pattern 3: Multi Model Fallback with Appropriate prompts</h2> <p>To mitigate the downside of Pattern 2, the system should store versioned, model-specific prompt templates.</p> <p><strong>Mechanism</strong>: When falling back from a high-reasoning model to a lower-tier one, the application swaps the prompt for one with more explicit few-shot examples or stricter constraints to maintain output parity.</p> <p><img src="../assets/429_4.png" alt="" /></p> <p><strong>Challenge</strong>: This increases the maintenance surface area. You are no longer managing one LLM integration, but an “N-model” matrix that requires robust evaluation (Evals) to ensure consistent behavior across all fallback paths.</p> <h2 id="pattern-4-event-driven-processing">Pattern 4: Event Driven Processing</h2> <p>By moving from a request response model we now ensure that there is no urgency to serve the response, We can control the following things by moving to a queue based model</p> <p><img src="../assets/429_5.png" alt="" /></p> <p><strong>Backpressure Absorption</strong>: The queue acts as a shock absorber for traffic spikes.</p> <p><strong>Concurrency Control</strong>: You can limit the number of active consumers to exactly match your provider’s Tier limits.</p> <p><strong>Prioritization</strong>: You can route “Premium User” requests to a priority lane while background tasks wait for available quota.</p> <h1 id="conclusion">Conclusion</h1> <p>External AI providers are distributed systems with shared, limited capacity. To build at scale, we must treat rate limits as a first-class architectural constraint rather than an edge case.</p> <p>Successful LLM platforms do not just retry; they orchestrate. They distribute traffic across providers, control global concurrency, and ensure prompts are portable enough to survive a provider’s downtime. Retries may recover from failures, but architecture determines whether those failures happen in the first place.</p> <p>PS: All diagrams have been generated with the use of AI Model (Gemini)</p> Thu, 19 Mar 2026 07:15:00 +0000 https://abinavravi.github.io/programming/ai/2026/03/19/designing-429s-llms.html https://abinavravi.github.io/programming/ai/2026/03/19/designing-429s-llms.html Programming AI How to Deliver Business value with AI systems <h2 id="introduction">Introduction</h2> <p>If you also want AI systems to deliver business value, you have come to the right place. To deliver proper business value there needs to be a deep understanding of how to create reliable systems that can consistently deliver value. Having a couple of machine learning models that do well on notebooks but can’t be put into production does the opposite.</p> <p>In this post, we will talk about how to think about a system that can deliver business value using machine learning effectively.</p> <h2 id="maturity-of-machine-learning">Maturity of Machine Learning</h2> <p>To deliver value there is a need to understand where we stand and what we need to provide. There are multiple models of the Machine Learning Operations cycle that can help us understand this scenario. Out of the different maturity models, the Azure MLops maturity model is the one I could completely relate to in increasing order of complexity and milestones.</p> <p>Since we are mostly concerned with designing machine learning systems in this post the emphasis from the Azure model is on the Model creation, Model release and application integration phase. The organization aspect of things isn’t covered in this post but is also a main pillar to ensure that there are teams of different strengths coming together to build a reliable system.</p> <p>Since we are concerned with bringing a machine learning model to production the emphasis will be on Model creation, Model release and integration with the application. There is another aspect of building cross functional teams of various capacity which we will not delve into detail in this blog post as that is a post for another day.</p> <p>The issues with most teams across the board is that data scientist generally come from a non engineering background and hence are required to learn skills beyond their paycheck and engineers need an understanding of machine learning which again exceeds their role capacity. The end result is that we have data scientist building a model and handing over to engineers to make it into deployable software into production.</p> <p>While you can refer to the <a href="https://learn.microsoft.com/en-us/azure/architecture/ai-ml/guide/mlops-maturity-model">machine learning maturity model</a> here and maybe look at the images below from <a href="https://techcommunity.microsoft.com/t5/ai-machine-learning-blog/mlops-maturity-model-with-azure-machine-learning/ba-p/3520625">here</a>. I would go on to talk about stages of deployment.</p> <h2 id="stages-of-machine-learning-deployment">Stages of Machine Learning deployment</h2> <h3 id="minimum-deployable-product">Minimum Deployable Product:</h3> <p>Like in a startup where there is a minimum viable product on which there are iterations performed we should start thinking about Minimum deployable product which can get the customer some value and is a move towards the grand utopia of no manual intervention anywhere in the ML training cycle.</p> <p>So let us start thinking about how to serve simple machine learning models into production first, the LLM world brings hardware challenges which is probably too much to aspire if the organisation hasn’t deployed even simple machine learning models.</p> <p>We would have a machine learning model at this point in time this can be stored at a cloud storage location or at the server. The first step is to wrap an API with endpoints that can take requests and can then return an inference value of some meaning.</p> <p>For example if the problem is a classification problem just returning a vector of 0 and 1 makes no sense to the end user. This API would do the conversion to possible categories and return value to the user that can be either consumed by the frontend client for display or by other services to do some processing.</p> <p>In addition to the API we should add some testing in the code unit tests to ensure that functions work at an implementation level and integration tests so that we know that it works with the entire system. How to write these tests is not our main focus now. Add a CI pipeline where we can check for builds and tests in an automated fashion whenever we push code into the repository. This should offer some basic software testing reliability to a model that has not seen production.</p> <p><img src="/ml/mlops/level0.png" alt="Level 0" /></p> <p><img src="/ml/mlops/level1.png" alt="Level 1" /></p> <h3 id="automatic-retraining">Automatic Retraining</h3> <p>Now that we have a minimum deployable version which is available as a containerised deployment in a container registry we should probably take a look at how can we achieve the next feat of making the retraining process smooth, so that in case of issues with the deployed model we can automatically get the data, perform pre-processing and then do a training of the model using the newer data.</p> <p><img src="/ml/mlops/level2.png" alt="Level 2" /></p> <p><img src="/ml/mlops/level3.png" alt="Level 3" /></p> <p>Let us take a look at some of the components and why they would be needed at this stage.</p> <ul> <li>Data Pipelines and data contracts: With data pipeline and data contracts we can fetch very reliable data that meets the input requirements of the model and the data contracts can ensure that this happens in a very type safe fashion.</li> <li>Data versioning: While we do retraining it is probably a good idea to maintain the version of the data using timestamps and other metadata requirements. Tools like DVC help us maintain versions and this is essential to create a reproducible training environment if there are issues with the training or any</li> <li>Training pipelines: Building Machine learning pipelines where it is probably good practice to use orchestration to run the preprocessing, training and testing as a part of single flow. By using orchestration tools we can modularize the code and recognize if there is any issues in a particular module.</li> <li>Model registry: Model registry can be thought of as a metadata store for models which can help version models, provide aliases, tag and annotate them, it provides an interface which solves when multiple versions and multiple models are produced by having something unique.</li> <li>Machine Learning monitoring: While a full fledged monitoring is not required an observability framework that can monitor the drifts in models, data is required and maybe an alerting system which can notify when the threshold of performance is declining can be present so that there is a manual intervention from the team on whether the models need to be retrained or not.</li> </ul> <p>While these components can add complexity to the existing workflow it is necessary to remove obvious mistake when scale of model creation increases. The best way to approach this would be to have a team that can maintain these components as a ML platform and the data scientists can be their internal customer who can use the platform.</p> <h3 id="complete-automatic-machine-learning-pipeline">Complete Automatic Machine Learning pipeline</h3> <p><img src="/ml/mlops/level4.png" alt="Level 4" /></p> <p>This stage is attained by very few companies where everything is automated and there is minimal manual involvement in making things work together. It is the utopia that people aim for when they start building an MLOps department. while there is minimal manual intervention needed in between components we would still need a team that can add or remove components perform some spring cleaning to keep the platform clean and technical requirements running up to data.</p> <h2 id="conclusion">Conclusion</h2> <p>While the blog limits it within the maturity model, there needs to be a deep dive into each component and this can be extremely challenging. While MLOps is still not a matured field each deployment choice can have different effects on the end product. My aim with this article was to bring some thought into what are different stages and how a beginner can approach each stage depending on their specific requirements.</p> <p>I havent covered the details of each component and that is something for the future. For starters I would recommend <a href="https://www.ravirajag.dev/">this blog series</a> for building a minimum deployable product version and then the journey deepens quite a bit.</p> Sat, 13 Apr 2024 07:15:00 +0000 https://abinavravi.github.io/machine/learning/operations/2024/04/13/Business-value-MLOps.html https://abinavravi.github.io/machine/learning/operations/2024/04/13/Business-value-MLOps.html Machine learning Operations A deep dive into Async patterns <p>In the recent times I have been trying to understand a bit more about asynchronous communication between services and real time streaming. For real time streaming the Pub sub pattern seems the most important architectural pattern.</p> <p>In this post I will go on a journey where we assume that we know about synchronous client server interaction to various async patterns and how each of them solve the problem of scale.</p> <h2 id="client-server-architecture">Client Server Architecture</h2> <p>In the world of application development which involves internet, there are basically two components one is the frontend/Client which is accessible through a browser or app where people can click or enter data and perform some actions, which is then sent across to the server (some form of a computer) that performs the logical operations on it. The data is relayed from client to server through a secure network connection.</p> <p><img src="/assets/CSarch.jpeg" alt="A simple example of Client Server Model" /></p> <p>As consumer we would want our actions also technically known as requests to be executed as fast as possible which is the right of the customer.</p> <h3 id="synchronous-communication">Synchronous Communication</h3> <p>While simple to implement, synchronous communication in client-server systems suffers from several limitations that impact scalability and responsiveness. Each request blocks the server, occupying resources (like RAM) until the entire logic executes. This creates a single thread of execution, meaning the server can only handle one request at a time. In multi-process systems, this forces you to allocate a dedicated machine for each customer, even if their requests take minimal processing time.</p> <p>This is why Synchronous communication can be disadvantageous for dynamic and scalable systems. This also brings in</p> <ul> <li>Inefficient use of compute power</li> <li>Scalability bottlenecks — There is only so much machines that can be provisioned at a time</li> </ul> <h3 id="asynchronous-communication">Asynchronous Communication</h3> <p>In an asynchronous communication pattern, the server does not immediately return a response. Instead, it initiates the request and allows the client to continue execution without waiting. The processing can then happen concurrently on the server, and the client receives a notification or the processed information at a later date.</p> <p>The detail lies in the implementation and if incorrectly implemented async await operations can be slower than synchronous communication patterns.</p> <h2 id="patterns-of-asynchronous-communication">Patterns of Asynchronous Communication</h2> <p>Now that we understand that asynchronous patterns are essential for building a scalable system let us try and understand different patterns of communication.</p> <ul> <li>Request Reply Pattern</li> <li>Publish Subscribe</li> <li>Fire and Forget</li> <li>Event Driven</li> <li>Websockets</li> </ul> <h3 id="request-reply-pattern">Request Reply pattern</h3> <p>The request-reply asynchronous pattern allows a client to send a request to a server without waiting for an immediate response. This is the pattern that is closest to the synchronous request reply pattern. This frees the client to continue execution on other tasks while the server processes the request concurrently. Once processing is complete, the server sends a response back to the client, often through a callback function or message queue. This pattern is particularly beneficial for tasks involving network calls, database interactions, or any scenario where the client doesn’t need to wait for the server’s response to proceed. It improves responsiveness and throughput by allowing the client and server to work independently. However, it introduces additional complexity compared to synchronous communication, as the client needs a mechanism to handle the eventual response.</p> <p>This pattern is generally implemented using async/await framework and the coroutines in languages such as python.</p> <p><img src="/assets/reqrep_pattern.jpeg" alt="Source: https://learn.microsoft.com/en-us/azure/architecture/patterns/async-request-reply" /></p> <h3 id="publish-subscribe-pattern">Publish Subscribe Pattern</h3> <p>The Publish-Subscribe pattern also known as pub sub is an alternative pattern of asynchronous communication. The advantage of pub sub over request reply is that pub sub patterns allows for a loose coupling between publishers and subscribers.</p> <p>The loose coupling is established by using a message broker component which uses topics to establish connection. The message broker efficiently routes the message to all interested subscribers. This pattern forms the backbone of microservices architecture.</p> <p>Some common implementations are message queues and event buses. Some of the open source implementations for usage is the RabbitMQ, Apache Kafka.</p> <p><img src="/assets/pubsub_pattern.jpeg" alt="Source: https://learn.microsoft.com/en-us/azure/architecture/patterns/publisher-subscriber" /></p> <h3 id="fire-and-forget-pattern">Fire and Forget Pattern</h3> <p>The fire-and-forget pattern is a simple approach to asynchronous communication where a sender transmits a message without waiting for a response or confirmation. This pattern prioritizes sending the message quickly and efficiently, and the sender does not track its delivery status.</p> <p>It’s often used for one-way tasks like sending logs, notifications, or initiating background processes. While fire-and-forget offers simplicity and speed, it lacks the guarantee of message delivery.</p> <p>Common implementations include message queues, email clients, or any system that allows sending messages without requiring feedback. However, it’s crucial to consider the potential for lost messages and design your system accordingly, especially if reliable delivery is critical.</p> <h3 id="event-driven-pattern">Event Driven Pattern</h3> <p>The event-driven pattern structures applications around the concept of events — significant occurrences within the system. Producers (components that trigger events) publish these events, carrying relevant data about the happenings. Consumers (components interested in these events) subscribe to specific events or categories.</p> <p>When an event is published, the event broker efficiently routes it to all interested consumers. Consumers then process the event information to perform their designated tasks.</p> <p>This loose coupling and asynchronous nature make event-driven systems highly scalable, responsive, and adaptable to changes. Common implementations include message brokers, event buses, and pub-sub systems configured to handle event routing and delivery.</p> <p>The event-driven pattern is well-suited for microservices architectures, real-time applications, and scenarios where components need to react to changes in the system without tight dependencies on each other.</p> <p><img src="/assets/event_driven_pattern.jpeg" alt="An example of event driven architecture Source: https://learn.microsoft.com/en-us/archive/msdn-magazine/2018/february/azure-event-driven-architecture-in-the-cloud-with-azure-event-grid" /></p> <h3 id="websockets">Websockets</h3> <p>WebSockets, the persistent two-way communication channels for web applications, thrive alongside asynchronous programming patterns. Here’s how they work together:</p> <ul> <li>Persistent Connection: Unlike traditional HTTP requests, WebSockets establish a long-lived connection between the client and server. This eliminates the need for repeated connection setup, improving efficiency.</li> <li>Asynchronous Communication: Both client and server can send and receive messages asynchronously, meaning they don’t have to wait for a response before sending the next message. This allows for real-time data exchange without blocking the main application flow.</li> <li>Event-Driven Model: WebSockets often leverage an event-driven approach. The server can push messages to the client, triggering event handlers on the client-side to react to the received data. This enables real-time updates and interactive experiences.</li> </ul> <h2 id="conclusion">Conclusion</h2> <p>While sync patterns are easy to implement async patterns bring real scalability to code that is written to bring software products to users.</p> <p>If readers notice any mistake please do mention in the comments and it will be corrected.</p> Sat, 30 Mar 2024 20:15:00 +0000 https://abinavravi.github.io/engineering/2024/03/30/Deep-dive-async.html https://abinavravi.github.io/engineering/2024/03/30/Deep-dive-async.html Engineering DSPy Programming Not prompting Sat, 20 Jan 2024 07:15:00 +0000 https://abinavravi.github.io/machine/learning/2024/01/20/DSPy.html https://abinavravi.github.io/machine/learning/2024/01/20/DSPy.html Machine Learning Python Package management with uv <h1 id="background">Background</h1> <p>Working as a Machine learning Engineer who deploys most of the stuff on the web downloading dependencies become a bottleneck at some point in time. When I started working we were using requirements.txt with versions and this was a britte setup where if by accident a version number could be changed unintentionally everything could cause issues, how to resolve this issue is when pyenv came but usability was a slight concern, then came poetry which I had been using for about 3.5 years. What was the problem that poetry solved</p> <p>It came with a lock file which could be regenerated if something went wrong a pyproject.toml file which where multiple configurations could be set and modified, but with time generating the lock file and just doing poetry install seemed a bit slow as poetry is a project that is written completely in python and that meant the GIL was a limiting factor.</p> <p>With PyO3 and rust bindings for python came a set of python packages which outsourced the major processing to rust and pydantic is one of the libraries that took this by rewriting their entire core library in rust and bringing some breaking changes with pydantic v2.0. So it was only a matter of time before package managers were also rewritten in rust. While the environment was right came out uv from astral which had some success stories of writing some key pythonic linting software such as ruff.</p> <h1 id="what-is-uv">What is uv?</h1> <p>uv is basically a drop in replacement for poetry and is incredibly fast. The documentation at uv says that it might be 10-100x faster. From anecdotal evidence it reduced our build times especially requirements installation by atleast 2-3x.</p> <h1 id="how-to-use-uv">How to use uv?</h1> <h2 id="installation">Installation</h2> <p>Follow this <a href="https://docs.astral.sh/uv/getting-started/installation/">documentation</a> to install the uv according to your operating system</p> <h2 id="project-usage">Project usage</h2> <p>A new project can be created with <code class="language-plaintext highlighter-rouge">uv init</code> if the repo already exists or if the repo doesnt exist then you can create a new project with <code class="language-plaintext highlighter-rouge">uv init &lt;reponame&gt;</code>. There are two types of projects that can be created</p> <ol> <li>applications</li> <li>Libraries</li> </ol> <p>a <code class="language-plaintext highlighter-rouge">uv init</code> creates an application project by default and we have use <code class="language-plaintext highlighter-rouge">uv init --lib</code> for the library project.</p> <p>with project creation the following files are created</p> <ul> <li>pyproject.toml</li> <li>.python-version</li> <li>README.md</li> <li>hello.py</li> </ul> <p>if the code needs to be a python package we can use <code class="language-plaintext highlighter-rouge">uv init --package</code> to create the corresponding build system and utils in pyproject.toml.</p> <p>For further information on usage please refer <a href="https://docs.astral.sh/uv/concepts/projects/init/">documentation</a></p> <h2 id="adding-dependencies">Adding dependencies</h2> Sat, 13 Jan 2024 07:15:00 +0000 https://abinavravi.github.io/programming/2024/01/13/package-management-uv.html https://abinavravi.github.io/programming/2024/01/13/package-management-uv.html Programming How Phone camera has destroyed the feeling of nostalgia? (Rant) <p>I have been on social media actively lurking around and liking posts, my posts are the occasional photo dump. I have never posted a instagram story nor do I intend to do anyday soon. Recently I saw that many of my real life friends go to a concert and then take a video of the concert while the performance is on. This somehow makes me want to grab phones of the audience and throw it away.</p> <p>Now I am not an unreasonable man who is saying you shouldnt take a 30s clip of a song to show your friends that you are in a concert. But off late I see a rush of stories or status that are filled with 30s of each song performed. Now I may sound old and like a boomer but what happened to just enjoying the performance and beauty of it. From my limited interactions with people who do this their justification is that We are saving this for memories.</p> <p>My retorting question is if you save it for the future by capturing it on a phone now, are you not living in the present? which brings me to the major opposition point to such behavior. The mankind has always lived on stories and nostalgia of some events from the past. When we meet for parties, dinner etc the conversation generally revolves around such memories and I feel not capturing all of them on a phone allows for some creative liberty in life. You can always add superlative adjectives and make your friends, family and acquaintances jealous of the fact. But if you do show some proof they can come to a judgement call about your memory and can easily spoil it for you.</p> <p>Over exaggeration while story telling brings character and that is being lost when every moment is captured on a phone and the actual events are being replayed and then arguments happen with evidence of the event. While this is legally quite helpful having a camera in the fun moments kind of spoil the feeling of nostalgia and imposes limits of creativity on the retelling of the event to a person.</p> Mon, 11 Sep 2023 23:45:00 +0000 https://abinavravi.github.io/life/2023/09/11/Phone-camera-Killed-nostalgia.html https://abinavravi.github.io/life/2023/09/11/Phone-camera-Killed-nostalgia.html Life My first Prefect ETL Pipeline <h2 id="problem-statement">Problem Statement</h2> <p>There is a business case where the organization is dependent on an API to fetch the data and luckily the data can be stored and used for downstream analytics later. This API costs a lot and the data also needs to be stored securely. But the idea is to not write a script which is put together of all the API calls panda conversions etc that will fail on the drop of a hat because it is meant as a one time usage</p> <h2 id="requirements">Requirements</h2> <p>The script should</p> <ul> <li>re runnable</li> <li>configurable</li> <li>fast velocity of development</li> <li>easy to maintain.</li> </ul> <h2 id="tasks">Tasks</h2> <ol> <li>Create a function that fetches the data from the API</li> <li>Convert the API response into a dataframe</li> <li>Store the dataframe in a database</li> <li>Create a pipeline that does this in a sequence.</li> </ol> <h2 id="solution">Solution</h2> <p>We are going to build the entire thing using prefect and python. I tried my hand at airflow but it just seemed so complex with binaries etc that prefect documentation seemed like a breeze.</p> <h3 id="0-install-prefect">0. Install prefect</h3> <p>Install this inside a vitual environment</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pip install -U prefect </code></pre></div></div> <h2 id="code-snippets">Code snippets</h2> <h3 id="1-create-a-function-that-fetches-data-from-api">1. Create a function that fetches data from API</h3> <p>Since the API call that I have to make is a post API call, the input data to be sent in the request is stored as a modifiable content in a json and then loaded during the task phase. This would be a task in the prefect universe which is a smaller brick in the larger pipeline represented as a flow.</p> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">requests</span> <span class="kn">import</span> <span class="nn">json</span> <span class="k">def</span> <span class="nf">fetch_data</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span> <span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="p">.</span><span class="n">post</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">json</span><span class="p">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">data</span><span class="p">))</span> <span class="k">return</span> <span class="n">response</span><span class="p">.</span><span class="n">json</span><span class="p">()</span> </code></pre></div></div> <h3 id="2-convert-the-api-response-into-a-dataframe">2. Convert the API response into a dataframe</h3> <p>Once the response is obtained as json convert it into a dataframe by using pandas to concat if the dataframe is not empty and if empty just create a dataframe from json</p> <h3 id="3-dumpt-the-data-to-a-postgresql-database-using-sqlalchemy-and-pandas">3. Dumpt the Data to a Postgresql database using SQLAlchemy and pandas</h3> <p>Create a engine for dumping the data using SQLAlchemy and then use df.to_sql() method from pandas to just dump the data into the postgres table</p> <h2 id="putting-the-above-parts-together">Putting the above parts together</h2> <p>steps 1,2 and 3 are individual tasks in the pipeline, now just write a simple python function which will basically execute this in sequence and then add a @flow decorator to the top of the function something like this</p> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kn">from</span> <span class="nn">prefect</span> <span class="kn">import</span> <span class="n">flow</span><span class="p">,</span> <span class="n">task</span> <span class="o">@</span><span class="n">task</span> <span class="k">def</span> <span class="nf">fetch_data</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span> <span class="p">...</span> <span class="o">@</span><span class="n">task</span> <span class="k">def</span> <span class="nf">convert_to_df</span><span class="p">(</span><span class="n">response</span><span class="p">):</span> <span class="p">...</span> <span class="o">@</span><span class="n">task</span> <span class="k">def</span> <span class="nf">dump_to_db</span><span class="p">(</span><span class="n">df</span><span class="p">):</span> <span class="p">...</span> <span class="o">@</span><span class="n">flow</span> <span class="k">def</span> <span class="nf">my_etl_pipeline</span><span class="p">():</span> <span class="n">response</span> <span class="o">=</span> <span class="n">fetch_data</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span> <span class="n">df</span> <span class="o">=</span> <span class="n">convert_to_df</span><span class="p">(</span><span class="n">response</span><span class="p">)</span> <span class="n">dump_to_db</span><span class="p">(</span><span class="n">df</span><span class="p">)</span> </code></pre></div></div> <p>Now all that needs to be done is to run this script as if running a python script and this accomplished ETL and the localhost at port 4200 gives the dashboard of the task execution etc. Such a simple way to run simple workflows</p> Sat, 09 Sep 2023 23:45:00 +0000 https://abinavravi.github.io/engineering/2023/09/09/My-First-ETL.html https://abinavravi.github.io/engineering/2023/09/09/My-First-ETL.html Engineering Private Python packages on Github and Gitlab <p>If we work in an industry setting we need private packages for using as libraries to share across teams working on same project. To do that we can use package registry in github and gitlab.</p> <h2 id="gitlab">GitLab</h2> <h3 id="requirements">Requirements</h3> <ul> <li>A deploy token pair with username and deploy key from gitlab repository</li> <li>A repository for this purpose</li> <li>poetry package management</li> </ul> <h3 id="steps">Steps</h3> <ol> <li>Create a repository with the name of the package and then put all the code inside the repository</li> <li>Create a <code class="language-plaintext highlighter-rouge">__init__.py</code> file inside the repository and import all the classes and functions that needs to be exposed to users of the package</li> <li><code class="language-plaintext highlighter-rouge">pip install poetry</code> to install poetry in the virtual environment</li> <li>Import the dependencies for the package by using <code class="language-plaintext highlighter-rouge">poetry add &lt;package name&gt;</code></li> <li>To ensure that package is maintained properly write tests to keep tabs on functionality</li> <li>Once everything is done then run the following three commands in sequence to build and push the package to gitlab repository <ul> <li><code class="language-plaintext highlighter-rouge">poetry config repositories.&lt;variable_name&gt; https://gitlab.com/api/v4/projects/&lt;project_id&gt;/packages/pypi</code></li> <li><code class="language-plaintext highlighter-rouge">poetry build</code></li> <li><code class="language-plaintext highlighter-rouge">poetry publish --repository &lt;variable_name&gt; -u &lt;gitlab_deploy_token_name&gt; -p &lt;gitlab_deploy_token&gt;</code></li> </ul> </li> </ol> <p>Now the pypi package is available for internal usage and can be installed by</p> <ul> <li><code class="language-plaintext highlighter-rouge">pip install &lt;package_name&gt; --no-deps --index-url https://&lt;gitlab_deploy_token_name&gt;:&lt;gitlab_deploy_token&gt;@gitlab.example.com/api/v4/projects/&lt;project_id&gt;/packages/pypi/simple</code></li> </ul> <h2 id="github">GitHub</h2> <p>I would like to thank my friend Abhijeet Parida for providing a template with a very beautiful readme to accomplish this task in <a href="https://github.com/a-parida12/poetry_pypi_template">Github</a></p> <h2 id="extensions">Extensions</h2> <p>Ideally should use a ci pipeline to create the packages so that there can be a versioning that can be automatically done</p> <h2 id="references">References</h2> <ol> <li>https://docs.gitlab.com/ee/user/packages/pypi_repository/</li> <li>https://docs.mpcdf.mpg.de/doc/data/gitlab/devop-tutorial.html</li> <li>https://github.com/a-parida12/poetry_pypi_template</li> </ol> Sun, 19 Feb 2023 23:45:00 +0000 https://abinavravi.github.io/engineering/2023/02/19/Private-Python-Packages.html https://abinavravi.github.io/engineering/2023/02/19/Private-Python-Packages.html Engineering Common Optimization Algorithms <h2 id="the-learning-process">The Learning Process</h2> <p>An important question to ask is what does it mean to learn in Machine Learning/Deep Learning? The answer is simple the goal of a Machine Learning model is to represent the knowledge of most data points with the help of a function which can either be linear or non linear. So how do we decide which function to choose to represent the data points? We use weights and biases to represent the function and randomly assign them a value, then we go on to then iteratively modify the weights with the help of cost function/loss function. When we minimize the cost function we then bring the prediction function closer to the data points.</p> <p>How to go about the minimization process? For this we use the optimization algorithms such as gradient descent, Stochastic gradient descent etc</p> <h2 id="the-gradient-descent-algorithm">The Gradient Descent Algorithm</h2> <p>The gradient descent algorithm is a first order optimization method which means that the highest order of derivative is first derivative. For gradient descent to be applied on the function there are two basic requirements. The function must be</p> <ol> <li>Differentiable - Derivative exists in all points of the domain of concern</li> <li>Convex - The second derivative is a positive value i.e. the function has one minimum value</li> </ol> <h3 id="what-is-a-gradient">What is a gradient?</h3> <p>In univariate calculus it is a derivate of the function and in multivariate calculus it represents the vector of derivatives with respect to a certain direction.</p> <h3 id="algorithm">Algorithm</h3> <p>The gradient descent algorithm is an iterative process (happens in a loop) until convergence is achieved. In layman terms consider moving down a mountain gradient descent can be said as the shortest number of steps that would be required to reach the valley. The pace at which we can get down is limited by the length of the steps and this is analogous to learning rate. If I were 30 ft tall I will reach in 5 steps opposed to 25 odd steps if I were 6ft tall.</p> <p>Please find a simple implementation of gradient descent in python below</p> <pre><code class="language-Python">import numpy as np def gradient_descent(start, gradient, learn_rate, max_iter, tol=0.01): steps = [start] # history tracking x = start for _ in range(max_iter): diff = learn_rate*gradient(x) if np.abs(diff)&lt;tol: break x = x - diff steps.append(x) # history tracing return steps, x </code></pre> <p>The code is from <a href="https://towardsdatascience.com/gradient-descent-algorithm-a-deep-dive-cf04e8115f21#:~:text=Gradient%20descent%20(GD)%20is%20an,e.g.%20in%20a%20linear%20regression">this blog</a></p> <h3 id="disadvantage">Disadvantage.</h3> <p>Though the approach is quite clean cut, since we are dealing with a large number of samples the calculation of the next step after going through all samples is very computation intensive. This is where there is a need for stochasticity and working in smaller batches and iterations. This method of performing gradient descent for random batches is known as <strong>Stochastic Gradient Descent</strong>.</p> <h3 id="momentum">Momentum</h3> <h2 id="adam-optimization">ADAM optimization</h2> <h2 id="other-optimization-algorithms">Other optimization algorithms</h2> Thu, 16 Feb 2023 21:45:00 +0000 https://abinavravi.github.io/machine/learning/2023/02/16/Optimization-Algos.html https://abinavravi.github.io/machine/learning/2023/02/16/Optimization-Algos.html Machine learning Cost Functions and Loss Functions in Machine Learning <h2 id="goal-of-machine-learning">Goal of Machine Learning</h2> <p>Machine Learning or Deep Learning can be viewed as function approximation based on data. What this means in simpler terms is that given a set of data points the aim is to get a function that can represent each of the data point very well and this function generalizes across many such similar data points.</p> <p>A simple polynomial curve fitting example is shown below. The idea of machine learning is to achieve something similar to left bottom figure so that there is a little bit of generalization or extrapolation that can be done if a sample comes from similar distribution.</p> <p><img src="https://abinavravi.github.io/assets/back2basics/curve_fitting.jpeg" alt="Function Approximation" /> [1]</p> <p>In case of the first diagram</p> <h3 id="loss-function">Loss Function</h3> <p>Loss function is the function that can depict the error between the predicted function value at a data point and the actual value. Loss functions are measured over single datum points.</p> <h3 id="cost-function">Cost Function</h3> <p>Cost function also denotes the error between predicted value and actual value but for a batch of data values.</p> <h3 id="mathematical-properties-of-loss-function">Mathematical properties of Loss Function</h3> <p>For a loss function these mathematical properties are important</p> <ul> <li>Differentiable in real domain completely</li> <li>Possibly convex to ensure that there is a minimum, but in case of deep learning the loss function landscape will generally not be convex and we will have to do with the local minimum.</li> </ul> <h3 id="common-loss-functions">Common Loss Functions</h3> <ul> <li><strong>Cross Entropy Loss</strong></li> </ul> <p>Cross entropy loss is generally used for classification problems and can be expressed mathematically as</p> <ol> <li>Multi label classification</li> </ol> \[L = \frac{1}{m} \sum_{i=1}^{m} y_i log(\hat{y}_i)\] <ol> <li>Binary classification</li> </ol> \[L = \frac{1}{m} \sum_{i=1}^{m} (y_i log(\hat{y}_i) + (1 - y_i log(1 - \hat{y}_i)))\] <p>where $y_i$ represents the label and $\hat{y}_i$ is the prediction for $m $ samples</p> <ul> <li><strong>Hinge Loss</strong></li> </ul> <p>This loss function was developed for the SVM classification methods</p> \[L = max(0, 1 - y* f(x))\] <ul> <li><strong>Mean Squared Error</strong></li> </ul> <p>Mean Squared error is generally used for regression based problems and can be represented mathematically as</p> \[L = \frac {\sum_{i=1}^{n} (y_i - \hat{y}_i)^2}{n}\] <p>Basically computes the distance between the sample and prediction and then averages it over n samples</p> <ul> <li><strong>Adversarial Loss function</strong></li> </ul> <p>Adversarial Loss is used in case Generative Adversarial networks where the discriminator and generator fight a zero sum game against each other.</p> \[\min_{G}\max_{D}\mathbb{E}_{x\sim p_{\text{data}}(x)}[\log{D(x)}] + \mathbb{E}_{z\sim p_{\text{z}}(z)}[1 - \log{D(G(z))}]\] <p>where G is the Generator and D is the discriminator</p> <h2 id="references">References</h2> <ol> <li>Figure 1.4, <a href="https://www.microsoft.com/en-us/research/uploads/prod/2006/01/Bishop-Pattern-Recognition-and-Machine-Learning-2006.pdf">Pattern Recognition and Machine Learning, Christoher Bishop</a></li> </ol> Tue, 14 Feb 2023 17:45:00 +0000 https://abinavravi.github.io/machine/learning/2023/02/14/cost-functions.html https://abinavravi.github.io/machine/learning/2023/02/14/cost-functions.html Machine learning