Jekyll2023-12-04T21:45:28+00:00https://akshayranganath.github.io/feed.xmlAkshay Ranganath’s BlogsBlogs about Media Optimization, Web Performance, SEO and web technology.rakshayAWS re:Invent 20232023-11-30T00:00:00+00:002023-11-30T00:00:00+00:00https://akshayranganath.github.io/Notes-from-AWS-reInvent-2023<p>AWS re:Invent 2023 could have been called <strong>Gen AI, Amazon Bedrock and Amazon Q</strong>.</p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto,w_650/blog/reInvent2023/reinvent-logo-2.png" alt="reinvent logo" /></p>
<h2 id="what-stood-out">What stood out?</h2>
<p>Amazon was pushing hard the idea that GenAI is transforming all businesses. However, the LLM models themselves are still being developed. So, customers need to use a trusted platform and build tools based on the known end-point offered by various AWS services. LLM Models can be plugged-in and replaced.</p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto,w_650/blog/reInvent2023/keynote-1.png" alt="" /></p>
<p><a href="https://aws.amazon.com/bedrock/">Amazon Bedrock</a>, <a href="https://huggingface.co/docs/transformers/model_doc/rag">Retrieval Augmented Generation (RAG)</a> and <a href="https://aws.amazon.com/q/">Amazon Q</a> were the services in most focus throughout the event.</p>
<h2 id="dig-deeper">Dig Deeper</h2>
<h3 id="data-security--governance">Data Security & Governance</h3>
<p>During various sessions, AWS team and customers educated about the widespread use of Generative AI capabilities. They did acknowledge that access-control and data protection were at the forefront. Teams may misuse the service or share sensitive data in ignorance. The solution was to use a service like Amazon Bedrock and leverage an LLM model.</p>
<p>LLMs hosted within Bedrock can be trusted to not use the data for further training. Since the access can be restricted using the <a href="https://aws.amazon.com/iam/">IAM</a>, data protection is better achieved. Higher level services like <a href="https://aws.amazon.com/kendra/">Kendra</a> and <a href="https://aws.amazon.com/opensearch-service/">OpenSearch</a> and further ensure the data access can be controlled.</p>
<h3 id="rag">RAG</h3>
<p>If you are familiar with <a href="https://www.langchain.com/">LangChain</a> or <a href="https://openai.com/blog/introducing-gpts">GPTs</a>, a lot of content would sound similar. The only difference was the use of AWS services to achieve the same functionality.</p>
<p>In one of the hands-on sessions, we built a RAG solution using this architecture.</p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto,w_650/blog/reInvent2023/full_architecture.jpg" alt="rag-deployment" />
[Source: shared as part of workshop]</p>
<p>When deployed, the data flow looks like this:</p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto,w_650/blog/reInvent2023/Amazon%20Bedrock.jpg" alt="" />
[Source: shared as part of workshop]</p>
<p>The team also shared an <a href="https://github.com/aws-samples/aws-genai-llm-chatbot">example Multi-Modal RAG powered application</a>.</p>
<p>Amazon also spoke about introducing GenAI assisted code through <a href="https://aws.amazon.com/codewhisperer/">Amazon CodeWhisperer</a>. The nice feature about this tool is that it can integrate with existing IDEs like VSCode. It can also be customized based on a customer’s repository so that the code generated is more context specific.</p>
<h3 id="keynotes">Keynotes</h3>
<p>A few other things that were launched/announced at the keynotes were:</p>
<ul>
<li>Amazon Bedrock is generally available.</li>
<li>Bedrock is HIPAA eligible and SoC compliant.</li>
<li><a href="https://aws.amazon.com/bedrock/guardrails/">Gaurdrails for Bedrock</a>, a service to implement responsible AI was launched.</li>
<li>New models of Claude and Llama were added to Bedrock.</li>
<li>Agents for Bedrock were launched.</li>
<li>Sagemaker has been updated to help in building LLM models.</li>
<li>Dr. Verner Vogels, the CTO of Amazon launched a site called the <a href="https://thefrugalarchitect.com/">Frugal Architect</a>. The website contains
<blockquote>
<p>Simple laws for building cost-aware, sustainable, and modern architectures</p>
</blockquote>
</li>
</ul>
<h3 id="expo">Expo</h3>
<p>At the Expo, I was impressed with MongoDB’s support for advanced capabilities in Vector search. This service is called <a href="https://www.mongodb.com/atlas">Atlas</a>.</p>
<p>I learned from DataDog that they support <a href="https://docs.datadoghq.com/synthetics/">Synthetics</a>, a service similar to synthetic testing offered by Catchpoint.</p>
<p>Lastly, at a session in one of the booths, I saw the use of <a href="https://www.langchain.com/langsmith">LangSmit</a> - a very nice way to trace <code class="language-plaintext highlighter-rouge">LangChain</code> calls and make the output more reliable.</p>
<h2 id="bottom-line">Bottom Line</h2>
<ul>
<li>GenAI is here for Enterprises.</li>
<li>RAG is the way to leverage GenAI with custom data & reduce hallucinations.</li>
</ul>rakshayAWS re:Invent 2023 could have been called Gen AI, Amazon Bedrock and Amazon Q.Putting Generative AI to Work - Conference2023-10-15T00:00:00+00:002023-10-15T00:00:00+00:00https://akshayranganath.github.io/Putting-Gen-AI-To-Work<p>Pack Publications ran a 3 day virtual conference on the topic <a href="https://www.packtpub.com/conference/put-gen-ai-to-work">Put Generative AI to Work</a> from October 11-13. I was fortunate enough to attend the conference. Here are the main learnings / take-aways.</p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto/blog/gen-ai-hero-image-2.jpg" alt="hero image" />
[Source: Bing Generate]</p>
<p>Although we can’t seem to escape the buzz around Gen AI, Gartner is predicting that we’ve hit the <em>peak of inflated expectations</em> in the hype cycle. From here on, we are going to see a steep fall followed by a realization that Gen AI is really good at certain tasks and not the best tool for others.</p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto/blog/gartner-ai-hype-cycle.png" alt="Gartner Hype Cycle" />
[Source: <a href="https://emtemp.gcom.cloud/ngw/globalassets/en/articles/images/hype-cycle-for-artificial-intelligence-2023.png">Gartner Hype Cycle</a>]</p>
<h2 id="my-learnings">My Learnings</h2>
<p>With this background, let’s take a whirlwind tour of different things that I picked up at the conference.</p>
<h3 id="panel-discussion">Panel Discussion</h3>
<p>In a panel discussion, the industry stalwarts had some sanguine observations.</p>
<ul>
<li>Unlike the technological progress in the past, the AI adoption will actually replace higher value jobs.</li>
<li>However, new jobs that we’ve not heard about will start to appear. <a href="https://www.linkedin.com/in/mariaparysz/">Maria</a> quipped that a 8 month experienced <em>prompt engineer</em> is considered a <em>tenured</em> employee in this new field!</li>
<li><a href="https://www.linkedin.com/in/denis-rothman-0b034043/">Dennis Rotham</a> observed that the job of programmers will remain. His quip - can you imagine someone sending a rocket to the moon with Gen AI created code?</li>
<li>They also highlighted the fact that AI (not necessarily <em>Gen AI</em>) has been around for quite some time. It is present in all things like aircraft management, automobiles, manufacturing and so many industries. These deployments simply did not get so much attention.</li>
</ul>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto/blog/predicting-future.jpg" alt="sorceror gazing into future" /></p>
<p>Their suggestion were to:</p>
<ul>
<li>start small - start learning about the world of AI and Gen AI.</li>
<li>Domain Experience is irreplaceable but AI skills can be automated away. Your tenure in industry still holds value.</li>
<li>Folks who can translate the business requirement to Data Scientists and translate back the technical clarifications from Data Scientists to Business are in absolutely necessary. AI Managers are critical.</li>
<li>When trying to implement a project, start small.
<ul>
<li>Start with something that you know and can understand.</li>
<li>These suggestions were almost the same ideas as the basics of agile programming!</li>
</ul>
</li>
</ul>
<h3 id="evolution-of-e-commerce">Evolution of e-Commerce</h3>
<p>The next session that I loved was by <a href="https://www.linkedin.com/in/somilguptaai/">Somil Gupta</a> on the possibilities of eCommerce evolution due to Generative AI. Unlike the gloom-and-doom scenario, this was refreshingly optimistic and covered a lot of ground.</p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto/blog/digitally-assisted-shopper.jpg" alt="evolution of ecommerce" /></p>
<ul>
<li><strong>Understanding Intent</strong>: Current mechanism of search is not optimal. Due to the way the search is designed, there is a wide chasm between our intent and query. For example, we may search <em>spiderman dress for 5 year old boy</em> when our intent is to <em>plan a birthday party in the theme of Spider Man for a 5 year old boy and 15 of his friends, including party supplies, T-Shirt and return gifts</em>.</li>
<li>
<p><strong>AI Assisted Commerce</strong>: Gen AI technologies can understand our intent better. They can <em>think through</em> the request and suggest steps and thus make the shopping experience less stressful. For example, a user could search for something like this:</p>
<blockquote>
<p>I am attending an office party. I’d like to order a stylish red dress suitable for the occasion that makes a statement. My budget is 150-200 dollars.</p>
</blockquote>
<p>With AI assisted search, this query can be broken down identify the features. Perhaps, the algorithm could ask clarifying questions like material desired, shipping preferences and then provide links to the dress.</p>
</li>
<li><strong>Product Personalization</strong>: Gen AI technologies when combined with other products like <em>plugins</em> can take personalization to a new level. For example, when a user tries to enroll for a course on AI, the system could extract the user’s LinkedIn and detect that they have not refreshed Math skills in 15 years. The system could come up with a hyper-personalized course with a 2-day introduction to Math skills followed by AI lessons tailored to the user’s domain.</li>
<li>Other ideas were around systems where there is one <em>orchestrator</em> model that talks to other AI models for specific inputs, combines the results and presents in a comprehensible manner. For example, a financial advisor model that talks to a Bonds model, a Stocks model and so on.</li>
</ul>
<p>I felt this was one of the best session that was looking into the future on what AI technologies can transform. Personally, I would have liked to see this as a Keynote session.</p>
<h3 id="prompt-engineering">Prompt Engineering</h3>
<p>Unlike the typical prompt engineering sessions where someone opens a ChatGPT interface and starts typing, the session by <a href="https://www.linkedin.com/in/valentina-alto-6a0590148/">Valentina Alto</a> took us under the hood on how GPT interprets the prompt. She then walked us through some advanced techniques to help design optimal user prompts. Here are some items that I noted down:</p>
<ul>
<li>Clear instructions are a must.</li>
<li>If you have a complex query, break it down into sub-tasks.</li>
<li>Force the system to slow down by asking it to explain it’s thinking, and seek justifications.</li>
<li>Be descriptive on how you’d like the system to answer.</li>
<li>Order within the prompt matters. Last few sentences have the most weight.</li>
<li>Repeat important or critical items.</li>
<li>Give the model a way to escape without hallucinating.</li>
</ul>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto/blog/human-architecting-prompt.jpg" alt="human architecting prompt" /></p>
<p>She then walked us through some advanced prompting concepts:</p>
<ul>
<li>Few show approach: Provide a few examples. This can help the model make it more purpose driven</li>
<li>Use cues</li>
<li>Use selection marks: Separation of example from prompt.</li>
<li>Break down tasks: Especially useful for mathematical prompts.</li>
<li>Chain of thoughts: Prompt the model to reason step-by-step. Take the o/p of previous step and use it as I/p for next step.</li>
<li>ReACT: (Reason then ACT) Useful for working with agents. Kind of similar to Chain of thoughts.</li>
</ul>
<p>For those of you who’d like to do deep, here are 2 papers that were suggested:</p>
<ul>
<li><a href="https://arxiv.org/abs/2210.03629?_x_zm_rtaid=sQFaRMZZRVKvXhf2hzTXug.1697125475126.1644179f012e680718223d4fe40f70e4&_x_zm_rhtaid=601">ReACT</a></li>
<li><a href="https://arxiv.org/pdf/2201.11903.pdf?_x_zm_rtaid=sQFaRMZZRVKvXhf2hzTXug.1697125475126.1644179f012e680718223d4fe40f70e4&_x_zm_rhtaid=601">Chain of thought</a></li>
</ul>
<h2 id="llm-training-hands-on-sessions">LLM Training Hands-On Sessions</h2>
<p>I also attended 2 sessions by <a href="https://www.linkedin.com/in/denis-rothman-0b034043/">Dennis Rotham</a>. I am not sure on the restrictions for sharing the code - so I’ll refrain from it. However, the primary take-away were:</p>
<ul>
<li>If you want to be in this field, focus on understanding the concept of <strong>Transformers</strong>. This is critical.</li>
<li>The math may <em>look</em> daunting but it is not.</li>
<li>Once the concept is clear, Dennis felt that the <em>wow!</em> factor of Gen AI would give away to <em>of course!</em>. And to the realization that there is really not <em>Gen</em> in <em>Gen AI</em>!</li>
</ul>
<p>We also had sessions by <a href="https://www.linkedin.com/in/clintb/">Clint</a> on security risks and mitigation steps when working with Gen AI. He introduced the <a href="https://owasp.org/www-project-machine-learning-security-top-10/">OWASP Top 10 for ML</a> and the mitigation strategies. A lot of these sounded like the standard but robust software engineering practices. One call-out for me was about the use of trained model. If a malicious actor were to feed bad data to a popular model, it can ingest this and produce wrong or harmful output.</p>
<p>If companies start to rely more on Open Source trained models, such kind of issues may rise in criticality.</p>
<h2 id="closing-thoughts">Closing Thoughts</h2>
<p>As a technology professional, my main thoughts at the end of the conference were the following:</p>
<ul>
<li>If we want to stay relevant, we need to understand some core concepts like <em>Transformers</em>.</li>
<li>Instead of trying to learn the cheat codes of <em>effective prompts</em>, we should invest time to learn how the AI systems break down the queries. This can help us build more <em>optimal prompts</em>. Such a design may require us to build our out API+front-end instead of relying publicly available interfaces.</li>
<li>Architects, Developers and Project Managers are very much a necessity. Domain Knowledge still has relevance.</li>
<li>Enterprises may start to adopt more of the Open Source Models and deploy them within their own cloud environments. This can help prevent data loss or leaking secure information.</li>
<li>Using technologies like <a href="https://github.com/langchain-ai/langchain">LangChain</a> will be akin to a sequential programming language. Each AI model may be like a function call and orchestrating them will deliver some business outcome.</li>
<li>Gen AI is not equal to ChatGPT. There is a lot more to to it!</li>
<li>Learn more about Hugging Face and the models being published on this platform.</li>
</ul>rakshayPack Publications ran a 3 day virtual conference on the topic Put Generative AI to Work from October 11-13. I was fortunate enough to attend the conference. Here are the main learnings / take-aways.AWS ReInvent Recap2022-12-06T00:00:00+00:002022-12-06T00:00:00+00:00https://akshayranganath.github.io/AWS-ReInvent-Recap<p>This year, I got a chance to attend the AWS re:Invent conference held in Las Vegas from November 28th to December 1st. It felt great to be back at an “in-person” event. The overall focus appeared to be on AI/ML. The content varied from setting up large, complex and ultra-powerful clusters to non-technical aspects like identifying & communicating bias in AI models. Apart from that, I got a chance to attend sessions on HTTP/3, Web Performance Metrics measurement and learning the <em>Working Backwards</em> principle of Amazon. Here are my notes.</p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto,w_1024/blog/reinvent2022/lfzaxzymqf4dveiltong.png" alt="AWS re:Invent logo" /></p>
<h3 id="boa318-build-a-fitness-activity-tracker-using-machine-learning">BOA318: Build a fitness activity tracker using machine learning</h3>
<p>The session was intended to help us understand machine learning. However, I may have been over-optimistic in my selection :-) This session probably required attendees to know a lot about ML and training models. So it kind of went over my head. For those interested, here is the overall architecture used in this session.</p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/w_650,f_auto,q_auto,e_sharpen/blog/reinvent2022/wmmqf5tunugprhk7gvr5.jpg" alt="" /></p>
<h3 id="accelerating-high-performance-video-transcoding-with-amazon-ec2">Accelerating high performance video transcoding with Amazon EC2</h3>
<p>This was a very interesting session. I learnt 2 new things.</p>
<h4 id="high-efficiency-streaming-protocol-hesp">High Efficiency Streaming Protocol (HESP)</h4>
<p>In this session, the presenters spoke about a mechanism of achieving ultra low latency streaming. Unlike normal streams, HESP has:</p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto/blog/reinvent2022/fxtmszolkqtvsatq3cre.jpg" alt="HESP" /></p>
<ul>
<li>HESP uses lower amount of buffering as compared to regular streaming</li>
<li>Every resolution in HESP has 2 streams - a supported resolution and a lower version stream to quickly switch if needed.</li>
<li>Each frame has an initialization stream. So switching between resolution is very easy.</li>
<li>So if the player had switched to a lower resolution frame, once the play back completes, the player can easily switch to the higher resolution frame immediately.</li>
</ul>
<p>The challenge with HESP is the rapid encoding requirements from ingest to delivery - especially when handling live streams. For this, the presenter proposed the use of Xilinx EC2 instances.</p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto/blog/reinvent2022/ounroeskajgtgltlosyp.jpg" alt="" /></p>
<h4 id="lc-vc-by-v-nova">LC-VC by V-Nova</h4>
<p>The second part of the session was by <a href="">V-Nova</a>. They presented on the topic of <a href="https://www.v-nova.com/lcevc-enhanced-video/">LCVC</a> enhancement of codecs. They spoke about the ability to convert existing still images and videos into immersive <a href="https://www.queppelin.com/what-is-six-degree-of-freedom/">6 degrees of freedom</a> experience. Since such experiences are going to be common, there is a need for delivering rich experience as well. However, coding-decoding on device is limited by the headset capabilities. So they proposed that the computing should be <em>split</em> between CDN and device. In fact, they coined a term, <em>Graphics Delivery Network (GDNs)</em> for handing these kind of content.</p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto/blog/reinvent2022/w8dc8pnpwkafkwwepusf.jpg" alt="" /></p>
<h3 id="com304-detect-and-resolve-biases-in-artificial-intelligence">COM304: Detect and resolve biases in artificial intelligence</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Virginie Mathivet
Modern Data Manager
TeamWork
</code></pre></div></div>
<ul>
<li>Every model has a bias in AI. Eg Google Translate has issues with gender.</li>
<li>Bias notebooks: https://github.com/VMathivet/reinvent2022</li>
<li>In most cases, biases don’t come from the scientist but from data.</li>
<li>Explainable AI (xAI) - ability to explain the underlying AI rules.</li>
</ul>
<p>Here are the broad points that she was trying to make during her talk.</p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto/blog/reinvent2022/qkkby3t6mhjrcktcfawd.jpg" alt="" /></p>
<h3 id="net401-deliver-great-experiences-with-quic-on-amazon-cloudfront">NET401: Deliver great experiences with QUIC on Amazon CloudFront</h3>
<p>Presented by <a href="https://en.wikipedia.org/wiki/Jim_Roskind">Jim Roskind</a>, this was an incredible journey on the evolution and thought process that went into the creation of <a href="https://quicwg.org/">IETF QUIC</a> protocol that has ultimately become the <a href="https://www.ietf.org/archive/id/draft-ietf-quic-http-34.html">HTTP/3</a> protocol. Here are some slides that I noted down.</p>
<p><em>What is HTTP/3</em></p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto/blog/reinvent2022/nhmcpg6ps8dksw8z0gts.jpg" alt="" /></p>
<p><em>How Head of Line Blocking is prevented in QUIC</em></p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto/blog/reinvent2022/kmxwltp8f33v3o3b4ft9.jpg" alt="" /></p>
<p><em>How packet loss is handled in QUIC?</em></p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto/blog/reinvent2022/gguvfgyuxddfkgqf5kj8.jpg" alt="" /></p>
<p>Further reading: At the end of the session, Jim asked us to read a short description explaining the protocol. Here’s the document that he reference: <a href="https://docs.google.com/document/d/1RNHkx_VvKWyWg6Lr8SZ-saqsQx7rFV-ev2jRFUoVD34/preview#!">MULTIPLEXED STREAM TRANSPORT OVER UDP</a>.</p>
<h3 id="sus201-detecting-deforestation-with-geospatial-images-and-amazon-sagemaker">SUS201: Detecting deforestation with geospatial images and Amazon SageMaker</h3>
<p>This was a very interesting session related to identifying large change based on satellite images. The use case was to use the satellite image before and after a large California fire and see the impact. Unfortunately, I had a customer issue and had to walk out.</p>
<h3 id="cmp314-how-stable-diffusion-was-built-tips-and-tricks-to-train-large-models">CMP314: How Stable Diffusion was built: Tips and tricks to train large models</h3>
<p>This was a join session between <a href="https://stability.ai/">Stability.ai</a> and AWS. Stability is famous for their <a href="https://stablediffusionweb.com/">Stable Diffusion</a>. One of the main speakers was <em>Emad Mostaque</em>, the CEO of Stability.ai. He made some very interesting observations on the development of AI.</p>
<ul>
<li>The whole world of large models and training was kick-started based on a paper titled <a href="https://arxiv.org/abs/1706.03762">Attention Is All You Need</a>.</li>
<li>Going forward, there are going to be a handful of companies that will create foundational models. This model is trained on images, videos, text, etc.</li>
<li>There will be a few hundreds of companies that will build on top of the general model and train (ie fine tune) it for generic tasks on one type of data. For example, StableDiffusion for images, ChatGPT for text and so on.</li>
<li>There will be thousands of companies that will use this domain specific model and train it for very specific task. For example, a car dealership company may train their model to detect dents and damages based on the images of a car.</li>
</ul>
<p>The second half of the talk was very deep architecture discussion on how StableDiffusion managed to create Super Computer like raw power using <a href="https://aws.amazon.com/hpc/parallelcluster/">AWS Parallel Cluster</a>.</p>
<p>Some of the fun launch information were:</p>
<ul>
<li>Stable diffusion now does hands :-)</li>
<li>Photorealism is now almost here. By next year, we should have the generative AI build the capability for photographer like quality.</li>
</ul>
<p><em>Created by StableDiffusion with the prompt “Artificial Intelligence looking like a divine being’</em>:</p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto/blog/reinvent2022/ue7cuq1njso4jq3hydji.jpg" alt="" /></p>
<h3 id="amz302-how-amazon-uses-better-metrics-for-improved-website-performance">AMZ302: How Amazon uses better metrics for improved website performance</h3>
<p>This was a second session by <a href="https://en.wikipedia.org/wiki/Jim_Roskind">Jim Roskind</a> that I attended at re:Invent. This was focused on performance testing. Although the focus was measuring and improving latency, I think the lessons hold true for most of the other perf metrics that we cover.</p>
<h4 id="why-current-measurements-are-broken">Why current measurements are broken?</h4>
<p>According to Jim, in the current model, people tend to use different percentiles for measuring performance. The expectation is the the performance distribution is something like this.</p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto/blog/reinvent2022/tuxbqyv0npv0dashcfwt.png" alt="ideal performance distribution" />
<a href="https://verdazo.com/wp-content/uploads/2011/07/lognormal-distributions.png">Source</a></p>
<p>However, when everybody knows that the metrics being tracked are p50, p90 and p95, the distribution in one organization became something like this.</p>
<blockquote>
<p>When a measure becomes a target, it ceases to be a good measure. - <a href="https://en.wikipedia.org/wiki/Goodhart%27s_law">Goodheart’s Law</a></p>
</blockquote>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto/blog/reinvent2022/jddyalbzpjk96nvkhyjk.jpg" alt="" /></p>
<p>So from a measurement perspective, nothing had changed. However, for real users, the performance had degraded. Jim called such measurements as <em>fenceposts</em>. Imagine each percentile is like a fence. Between 2 measures is a lot of free land where sheep can graze. In an ideal world, the fence are supposed to graze all over the free space between the fence. However, when this kind of measurement is used, it is similar to the sheep collecting together near the fence. So this presents 2 kinds of major issues:</p>
<ul>
<li>no initiative to fix if within target..</li>
<li>no difference in how bad “bad” is ..</li>
</ul>
<h4 id="jims-solution---trimmed-mean">Jim’s Solution - Trimmed Mean</h4>
<p>The suggestion from Jim and team was that we should start to consider the <a href="https://en.wikipedia.org/wiki/Truncated_mean">Trimmed Mean</a> as a better metric.</p>
<blockquote>
<p>A trimmed mean is a method of finding a more realistic average value by getting rid of certain erratic observations. Under this method, a percentage of highest and lowest values are cut out from both the extremes before calculating the mean. This pre-calculation elimination results in a more reliable mean value. <a href="https://www.wallstreetmojo.com/trimmed-mean/">Source</a></p>
</blockquote>
<p>Here’s a simple calculation from the <em>WallStreetMojo</em> site:</p>
<p><img src="https://cdn.wallstreetmojo.com/wp-content/uploads/2021/09/Trimmed-Mean.jpg.webp" alt="" /></p>
<p>In the past, mean (i.e. average) was considered a bad metric because the outliers could have extremely high impact. By using trimmed mean, we discard these outliers and then count everything to find out an <em>average</em> number. The advantages are:</p>
<ul>
<li>it is a single number.</li>
<li>once the percentile to be discarded is fixed, this metric will include all measurements.</li>
<li>is is impacted by each measure and will not blind to “fencing” effect described earlier.</li>
</ul>
<p>By adopting a trimmed mean 90 (tm90) metric, Amazon was able to improve its webpage latencies.</p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto/blog/reinvent2022/dirdybgvunov6x47oxzf.jpg" alt="" /></p>
<p>After Jim’s talk, other AWS architects presented the Cloudwatch metrics and showed the ways to generate this metric from the data. They also informed us that Cloudwatch RUM is a solution and that can be used for real user monitoring.</p>
<h3 id="aim342-advancing-responsible-ai-bias-assessment-and-transparency">AIM342 Advancing Responsible AI: Bias Assessment and Transparency</h3>
<p>Peter Hallinan Sr Manager AI and Dr. Alicia Sagae Research Scientist, AI</p>
<p>This workshop was aimed at helping generate a discussion around the potential for bias in AI and the mechanism to bubble it up and communicate it. In traditional software development, we always try our best to articulate the requirements, assumptions and scope. In AI projects, this has not necessarily been done. One of the take-aways was to figure out a way to create a process to explain and communicate the assumptions.</p>
<p>The starting point was a walk through on the concepts of <em>equality</em> and <em>equity</em>.</p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto/blog/reinvent2022/ro8w70totynw24et581s.jpg" alt="" /></p>
<p>The hands-on workshop aimed to help us identify if there are any <em>unwanted bias</em> in our AI system.</p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto/blog/reinvent2022/dpflte9albamtf83bpzk.jpg" alt="" /></p>
<p>During the workshop, we used a simple <a href="https://github.com/aws-samples/reinvent2022-advancing-responsible-ai">Python notebook</a>. Using the modified MNIST number recognition program we did the following:</p>
<ul>
<li>Calculate the confusion metrics for number recognition. We thought it was pretty good since accuracy was over 80%.</li>
<li>When we broke it down, we realized the accuracy for specific numbers was much lower (~50%).</li>
<li>We had discussion at this point on what it would mean in real world. Suppose number recognition is go/no-go on mortgages. One group would be disproportionately be rejected.</li>
<li>The next step was to identify the number of samples and identify if there were patterns. The numbers that had a lower accuracy had lower training samples. We then discussed if additional training samples would improve the accuracy.</li>
<li>We then explored adding an additional dimension of color and then running the accuracy comparison based on multiple parameters like the type of digit (curved, linear) and color (orange, red).</li>
</ul>
<p>We closed it out with a few pointers on taking this discussion outside of the session.</p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto/blog/reinvent2022/wfgow4e1tcoms8uv8tmz.jpg" alt="" /></p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto/blog/reinvent2022/mdrdferli8nkiwoqaekp.jpg" alt="" /></p>
<p>The AWS team finally closed the session by introducing their latest offerings that helps in specifying the AI model, its data, potential bias so that the consumers are aware of it and can build the necessary work-arounds.</p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto/blog/reinvent2022/gzdixxscf0juq33z16nf.jpg" alt="" /></p>
<p>Apart from these session, I attended a session on <a href="https://aws.amazon.com/blogs/opensource/working-backwards-the-story-behind-the-aws-cloud-development-kit/"><em>Working Backwards</em></a>. The resources on Amazon website are a much better resource and I’ll not be able to do any justice to it! So please refer to them for details!</p>rakshayThis year, I got a chance to attend the AWS re:Invent conference held in Las Vegas from November 28th to December 1st. It felt great to be back at an “in-person” event. The overall focus appeared to be on AI/ML. The content varied from setting up large, complex and ultra-powerful clusters to non-technical aspects like identifying & communicating bias in AI models. Apart from that, I got a chance to attend sessions on HTTP/3, Web Performance Metrics measurement and learning the Working Backwards principle of Amazon. Here are my notes.Comparing Animated Image Formats2022-08-03T00:00:00+00:002022-08-03T00:00:00+00:00https://akshayranganath.github.io/Comparing_Animated_Image_Formats<p>For a long long time, GIF has been the <em>de-facto</em> format for rendering animated images. However, did you know that most other image formats too support animation? I asked this exact same question on LinkedIn and here were the results.</p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto,w_1080/blog/survey-result.png" alt="LinkedIn Survey results" /></p>
<p>The reality is that animated images are supported by all of the following:</p>
<ol>
<li>Gif</li>
<li>Animated PNG (APNG)</li>
<li>Animated WebP and</li>
<li>Animated AVIF</li>
</ol>
<p>In this short article, I wanted to cover the pros and cons of the various formats. We’ll go over the formats, and finally see the link for each image type and the compression we can achieve when using different formats.</p>
<p>For this article, let’s consider these 2 Gif images. I have taken these from <a href="https://giphy.com/gifs/happy-birthday-hbd-hb-onPMdPD9wI4rWA6KaT">Giphy website</a>.</p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto/blog/happy_birthday.gif" alt="happy birthday original GIF" /></p>
<p>This image is 96.05 KB for 384x480 resolution image. It is not very large.</p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto/blog/car-race.gif" alt="car race" /></p>
<p>This image is 1.04 MB for 800x600 size. I picked this up from <a href="https://cdn.dribbble.com/users/2935848/screenshots/6641649/race-car.gif">here</a>.</p>
<h2 id="gif">GIF</h2>
<p>GIF stands for <em>G</em>raphical <em>I</em>nterchange <em>F</em>ormat. This is the grand-daddy of web images. For a long time, it was the <em>only</em> format that supported multiple frames and thus animated images.</p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto,w_1080,e_sharpen/blog/gif-support.png" alt="GIF Support" /></p>
<p>Source: <a href="https://caniuse.com/?search=gif">https://caniuse.com/?search=gif</a></p>
<h3 id="pros">Pros</h3>
<ul>
<li>Extremely wide browser support - everybody can support it.</li>
<li>Easy access. In fact, everything on GiPHY or similar website is a GIF image</li>
</ul>
<h3 id="cons">Cons</h3>
<ul>
<li>For longer animations, GIF can be very large in size.</li>
<li>GIF offers minimal compression. Other formats can do a better job.</li>
</ul>
<h2 id="png">PNG</h2>
<p><em>P</em>ortble <em>N</em>etwork <em>G</em>raphics file was the next format that arrived on the scene. Although PNG natively does not support animation, Mozilla worked on it and added the support through <a href="https://en.wikipedia.org/wiki/Portable_Network_Graphics#Animation">APNG extension</a>. Currently, all major browsers support animated PNGs. IE11 is the only hold up. If you (still) need to support IE11, you have other larger problems than just animated images!</p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto,w_1080,e_sharpen/blog/apng_support.png" alt="APNG Support across browsers" /></p>
<p>Source: <a href="https://caniuse.com/?search=apng">https://caniuse.com/?search=apng</a></p>
<h3 id="pros-1">Pros</h3>
<ul>
<li>For medium to larger images, APNG offers better compression and hence smaller size.</li>
<li>APNG can also support more colors than GIF.</li>
</ul>
<h3 id="cons-1">Cons</h3>
<ul>
<li>Since it is not a familiar format, not all tools may support it.</li>
</ul>
<h2 id="animated-webp">Animated WebP</h2>
<p>WebP is an image format that was released by Google. After Safari adopted it, this format now has wide support across browsers. WebP can support both lossy and lossless animated image creation. According to <a href="https://en.wikipedia.org/wiki/WebP#Animation">claims by Google</a>, this format can offer 64-19% reduction in size.</p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto,w_1080,e_sharpen/blog/webp_support.png" alt="WebP Support" /></p>
<p>Source: <a href="https://caniuse.com/?search=webp">https://caniuse.com/?search=webp</a></p>
<h3 id="pros-2">Pros</h3>
<ul>
<li>WebP has been supported by Chrome and Firefox for a long time. After Edge adopted Chromium as the browser engine, WebP has been available here as well.</li>
<li>Safari added support since Mac OS 11 (Big Sur) and from Safari 14 on Mobile devices. So WebP is now available across all browsers that generally matter.</li>
</ul>
<h3 id="cons-2">Cons</h3>
<ul>
<li>Lossy format can degrade the quality seriously.</li>
<li>Editing tools may not easily support exporting an animated image to WebP format.</li>
</ul>
<h2 id="animated-avif">Animated AVIF</h2>
<p><em>AV</em>1 <em>I</em>mage <em>F</em>ile format is the latest format to have hit the market. Launched during 2019, this file format has shown to provide better compression and fidelity at the same file size. Being a relatively newer format, it still has some time before widespread adoption.</p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto,w_1080,e_sharpen/blog/avif_support.png" alt="AVIF Support" /></p>
<p>Source: <a href="https://caniuse.com/?search=avif">https://caniuse.com/?search=avif</a></p>
<h3 id="pros-3">Pros</h3>
<ul>
<li>Much lower file size for similar quality than all other formats.</li>
</ul>
<h3 id="cons-3">Cons</h3>
<ul>
<li>Lacks browser support - most notably from Edge and Safari. However, this is just a matter of time. Safari has already launched a <a href="https://9to5mac.com/2022/07/15/apple-avif-image-safari-ios-16-macos-13/">tech preview</a> for AVIF.</li>
<li>Many tools including <a href="https://imagemagick.org/">ImageMagick</a> <a href="https://github.com/ImageMagick/ImageMagick/issues/2788">don’t have full support</a> for animated AVIF.</li>
<li>Consequently, a lot of tools may not support exporting animated images to this format.</li>
</ul>
<h2 id="mp4">MP4</h2>
<p>This is an outlier here. MP4 is actually a video format. However, any animation can be rendered as a video. Video formats offer much higher compression because they can compare individual frames and record just the differences. As a best practice, consider using a <code class="language-plaintext highlighter-rouge">video</code> tag with <code class="language-plaintext highlighter-rouge">autoplay</code>, <code class="language-plaintext highlighter-rouge">muted</code> and <code class="language-plaintext highlighter-rouge">loop</code> turned on. This will provide the same effect as an animated GIF.</p>
<p>However, a flip side to it is that many email clients do not support <code class="language-plaintext highlighter-rouge">video</code> tags. So embedding video in such cases may not be feasible.</p>
<h2 id="formats-compared">Formats Compared</h2>
<p>Now, let’s compare the different formats. For all images, I will be applying the <a href="https://cloudinary.com/documentation/image_optimization#automatic_quality_selection_q_auto"><code class="language-plaintext highlighter-rouge">q_auto</code> transformation</a>. This will ensure we can reduce the file size suitable for the user without changing the image format.</p>
<table>
<thead>
<tr>
<th>Format</th>
<th>Small Image URL</th>
<th>Small Image Size (KB)</th>
<th>Savings</th>
<th>Large Image URL</th>
<th>Large Image (KB)</th>
<th>Savings</th>
</tr>
</thead>
<tbody>
<tr>
<td>Baseline (GIF)</td>
<td><a href="https://akshayranganath-res.cloudinary.com/image/upload/v1659131715/blog/happy_birthday.gif">HP-GIF-baseline</a></td>
<td>96.05</td>
<td>0.00</td>
<td><a href="https://akshayranganath-res.cloudinary.com/image/upload/v1659130929/blog/car-race.gif">Race-GIF-baseline</a></td>
<td>1040</td>
<td>0.00</td>
</tr>
<tr>
<td>GIF</td>
<td><a href="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto/blog/happy_birthday.gif">HP-GIF</a></td>
<td>96.05</td>
<td>0.00</td>
<td><a href="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto/blog/car-race.gif">Race-GIF</a></td>
<td>1040</td>
<td>0.00</td>
</tr>
<tr>
<td>APNG</td>
<td><a href="https://akshayranganath-res.cloudinary.com/image/upload/fl_apng,f_png,q_auto/blog/happy_birthday.gif">HP-PNG</a></td>
<td>117.1</td>
<td>121.92</td>
<td><a href="https://akshayranganath-res.cloudinary.com/image/upload/fl_apng,q_auto/blog/car-race.png">Race-PNG</a></td>
<td>786.87</td>
<td>75.66</td>
</tr>
<tr>
<td>WebP</td>
<td><a href="https://akshayranganath-res.cloudinary.com/image/upload/q_auto/blog/happy_birthday.webp">HP-WebP</a></td>
<td>67.22</td>
<td>69.98</td>
<td><a href="https://akshayranganath-res.cloudinary.com/image/upload/q_auto/blog/car-race.webp">Race-WebP</a></td>
<td>1013.39</td>
<td>97.44</td>
</tr>
<tr>
<td>AVIF</td>
<td><a href="https://akshayranganath-res.cloudinary.com/image/upload/q_auto/blog/happy_birthday.avif">HP-AVIF</a></td>
<td>32.14</td>
<td>33.46</td>
<td><a href="https://akshayranganath-res.cloudinary.com/image/upload/q_auto/blog/car-race.avif">Race-AVIF</a></td>
<td>47.31</td>
<td>4.55</td>
</tr>
<tr>
<td>MP4</td>
<td><a href="https://akshayranganath-res.cloudinary.com/image/upload/f_auto:video,q_auto/blog/happy_birthday.gif">HP-MP4</a></td>
<td>32.1</td>
<td>33.42</td>
<td><a href="https://akshayranganath-res.cloudinary.com/image/upload/f_auto:video,q_auto/blog/car-race.gif">Race-MP4</a></td>
<td>15.8</td>
<td>1.52</td>
</tr>
</tbody>
</table>
<p>A few observations:</p>
<ul>
<li>AVIF is incredibly small at just 4.6% of the original image size for the large image. It also offers best compression on the small as well as large image.</li>
<li>PNG appears to offer decent compression when the original GIF is large while it actually adds bytes when trying to work with a smaller GIF.</li>
<li>WebP on the other hand does a decent job on the small GIF but not so well on the large GIF.</li>
<li>The old-school MP4 can beat all animated formats easily. Consider replacing animated images with a video for much better compression!</li>
</ul>
<h2 id="summary">Summary</h2>
<p>In short, the newer formats like animated WebP and AVIF do hold a lot of promise. If AVIF can actually delivery, the savings are very significant. That being said, the compression offered by a specific format can vary based on the actual image. So enforcing a fixed format may not be the best mechanism to achieve the most optimal file size.</p>
<p>If you are interested to work with Cloudinary, we have an option to enable <a href="https://cloudinary.com/documentation/image_optimization#automatic_format_selection_f_auto">automatic format selection <code class="language-plaintext highlighter-rouge">f_auto</code></a> to handle this complexity. When combined with the quality parameter (<code class="language-plaintext highlighter-rouge">q_auto</code>), we can make a decision about the right image format <em>based on that image features</em>.</p>
<p>Finally, to re-iterate my point - replace animated images with a video whenever possible. This will give you a much better compression than all other image formats!</p>rakshayFor a long long time, GIF has been the de-facto format for rendering animated images. However, did you know that most other image formats too support animation? I asked this exact same question on LinkedIn and here were the results.Notes from Bhakti School of Vedanta by Tapasyananda2022-06-17T00:00:00+00:002022-06-17T00:00:00+00:00https://akshayranganath.github.io/Notes-from-Bhakti-Schools-of-Vedanta<p>After listening and reading to the introductory <em>Advaita</em> Vednata book, <a href="/Notes-from-Vedantasaara-Sadananda/">Vedanta Saara</a>, I was intrigued to understand the core teachings of the alternative schools. In his talk, <em>Swami Sarvapriyananda</em> had spoken about the book, <a href="https://www.vedanta.com/store/bhakti_schools_of_vedanta.htm">Bhakti Schools of Vedanta</a>. I was fortunate enough to find a copy and some time to read through it. Here are some quick notes from this book.</p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto,w_650,h_650,c_pad/blog/bhakti-school-of-vedanta.jpg" alt="Bhakti Schools of Vedanta" /></p>
<p><a href="https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Ftse2.mm.bing.net%2Fth%3Fid%3DOIP.Buq05IwHHZTfJdcY0zEPZAAAAA%26pid%3DApi&f=1">Source</a></p>
<blockquote>
<p>The common object of all these systems may be stated thus: They seek to establish the supremacy of the Divine Personality, known under the different sacred names of Purushottama, Narayana, Vasudeva, Krishna, etc. and equate Him with Brahman the Absolute of the Upanishads. For them, the Supreme Being is Person with atributes and there is no Absolute beyond Him. They also lay stress on the exclusive position of devotion and Divine grace as the only means to overcome the hold of Karma on the Jiva and enable him to attain salvation. Salvation or release from the hold of Karma does not mean for them the mergence of the Jiva in Brahman, but attaining to the status of an eternal servant of His, which alone can give unalloyed bliss to the Jiva. Most of these teachings are theological… p31</p>
</blockquote>
<p>All the Vaishnava schools accept the nine forms of devotional disciplines mentioned in the Bhagavata Purana:</p>
<ol>
<li><em>Shravana</em> hearing recitals and expositions of divine excellences</li>
<li><em>Kirtana</em> choral singing of the Lord’s praise</li>
<li><em>Smarana</em> constant remembrance of Him through Japa, meditation, etc.</li>
<li><em>Paadaseva</em> service of the world recognizing it as a Paada or aspect of God</li>
<li><em>Archana</em> worship of Him in images</li>
<li><em>Vandana</em> salutation which consists in an attitude of genuine courtesy to all as temples of God</li>
<li><em>Dasya</em> cultivating the attitude that one is servant of God</li>
<li><em>Sakhya</em> sense of intimacy with Him</li>
<li><em>Atmanivedana</em> surrender of one’s self and everything to him. p231</li>
</ol>
<h2 id="sri-ramanuja-philosophy">Sri Ramanuja Philosophy</h2>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto,w_350,h_350,c_pad/blog/ramanuja.jpg" alt="Sri Ramanujaacharya" /></p>
<p><a href="https://upload.wikimedia.org/wikipedia/commons/9/93/Ramanujacharya.jpg">Source</a></p>
<h3 id="theory-of-creation-and-problem-of-evil">Theory of creation and problem of evil</h3>
<p>There is no absolute originals as souls (Jivas) and changeful nature (Jagat) always exist as a part of Brahman as His body or mode. They exist in the two states of latency (Pralaya) and patency (manifestation or Sristi). Pralaya and Sristi are eternally continuing states of universal Nature like night and day.. p43</p>
<p>Being an eternally recurring cyclic process, God is free from the responsibility of starting it and causing the evils accruing from it. It is Karma, the result of the action of Jivas in previous embodiments, that causes the good and evil, enjoyments and sufferings of Karma which have got necessarily to be enjoyed or suffered by those responsible for them. God does not create those efficiencies as He does not create Nature… God only provides the manifestation power. He is not responsible for the evil and sufferings involved in the creating process.</p>
<p>Knowledge for the Jiva consists in his recognition of his being only an absolutely dependent entity whose purpose is only to serve the Lord and not gain any personal enjoyment apart from it. p46</p>
<p>Unlike in Sankara’s system, there is nothing like subject-objectless consciousness in Visistadvaita metaphysics. Such a conception is dubbed as a metaphysical fiction. p56</p>
<h3 id="freedom-of-will">Freedom of will</h3>
<p>(<em>My summary</em>)
In this system, God only wills fruictification of Karma accrued by the Jiva. God is like light - it can be used for forging or reading scriptures. The merit or demerit devolves entirely on the person concerned and not on the light. The Jiva when it identifies with body-mind may accrue bad Karma. Knowledge is identification of the Jiva as only a Sasira (body) of God and he is a Sesa (servant) of Lord will all the actions be burnt in the fire of knowledge.</p>
<p>.. the most intimate and personalized name for the Supreme Being is Naraayana synonymous with Vishnu. Naraayana means He who is the ayana (dwelling place) i.e. the source, support and dissolving ground of all Naras or Jivas including inert matter too. p69</p>
<h3 id="problem-of-theology">Problem of Theology</h3>
<p>In the Semitic religions which uphold the idea of a formless God with human attributes, religion becomes gradually the acceptance of certain dogmas and social practices. Prayers become petitions addressed to some vague entity. Gradually social cohesion and not spiritual experience, becomes their aim and religion becomes highly politicized.</p>
<h2 id="sri-nimbraka">Sri Nimbraka</h2>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto,w_350,h_350,c_pad/blog/nimbraka.jpg" alt="Nimbraka" /></p>
<p><a href="https://cdn.britannica.com/11/133411-050-F57DAED3/Nimbarka-Sri-Golok-Dham-Ashram-New-Delhi.jpg">Source</a></p>
<p>Termed as द्वैताद्वैत, this philosophy is called <em>duality in unity</em> and is very similar to the भेदाभेद <a href="https://en.wikipedia.org/wiki/Bhedabheda">(Bhedaabheda) philosophy</a> of Bhaskara adopted to the <em>Vaishnava</em> theology.</p>
<p>Bhaskara criticized the two tiers of Reality, the really real पारमार्थिक (Paramaarthika) vs the apparently real व्यवहारिक (Vyavahaarika). He claimed that this is not mentioned in the <em>Upanishads</em> and was adopted from the शून्यवाद (ie Nihilistic school of Buddhism).</p>
<p>For Nimbraka,</p>
<blockquote>
<p>God is essentially formful and the substrate of all auspicious attributes. When the Upanishads speak of Him as <em>nirguna</em>, it only means that He is not subject to the Gunas or Prakriti. So also <em>nirvishesha</em> (without attributes) means He is without attributes born of neiscience as in the case of wordly objects to whom those attributes are limitations. p94</p>
</blockquote>
<h3 id="kinds-of-jivas">Kinds of Jivas</h3>
<p>Though all Jivas are potentcies of Brahman, Nimbraka’s system recognizes a kind of Taratmaya, gradation, among them. Some of them are Nityamuktas or eternally free. They had never been in bondage. They are eternally engaged in Divine service as His ornaments.. Then there are the bound souls, Baddhas. Some of them are मुमुक्षु (Mumukshus) or seekers after libration striving for that consummation. There are also some others oblivious to spiritual values and are wallowing in worldliness. They are Nitya-baddhas, the eternally bound. p97</p>
<h2 id="sri-madhavacharya">Sri Madhavacharya</h2>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto,w_350,h_350,c_pad/blog/madhava.jpg" alt="Sri Madhavacharya" /></p>
<p><a href="https://upload.wikimedia.org/wikipedia/commons/b/b3/Jagadguru_Madhvacharya.jpg">Source</a></p>
<h3 id="dvaita-philisophy">Dvaita Philisophy</h3>
<p>Madhava</p>
<blockquote>
<p>preferred to call his system emphaticaly as pure dvaita (Dualism) - the doctrine of Reality as having two aspects the स्वतन्त्र (svatantra / Independent) and the परतन्त्र (paratantra / Dependent). The Independent is God or Brahman, and the Dependent are the Jiva (soul), Prakriti (Primordial Matter) and other ontological entities. The difference between the Independent and the Dependent is complete and eternal, as it is the basic and irrevocable nature of Reality. p128 The Dvaita is further elaborated into पञ्च बेध (5-fold difference). The 5 differences are between:</p>
</blockquote>
<ol>
<li>Jiva and Jiva</li>
<li>Ishvara and Jiva</li>
<li>Ishvara and Jada</li>
<li>Jada and Jiva</li>
<li>Jada and Jada (p144)</li>
</ol>
<h3 id="metaphysics">Metaphysics</h3>
<p>Madhava defines a valid sense experience as यथार्थ (yathartha), knowledge of facts as they are. The fact experienced may rapidly or slowly undergo change, but that does not subtract from its reality. Permanence of any nature is not necessary for any entity to be real.</p>
<p>In Madhava’s system of realism, consciousness is always bi-polar - that is, there must be a knower ज्ञाता (jnaata) at one end, and an object ज्ञेय (gneya) at the other end. There is nothing like subject-objectless consciousness. This holds true for dreamless sleep.</p>
<p>The significance of this is that there are two types of objective perception - one through the meditation of the mind alone and the other through sense contacts with outside objects. p129</p>
<h3 id="theory-of-evil">Theory of Evil</h3>
<p>(My summary)</p>
<p>In Madhava’s system, the Independent and Dependent co-exist and the Dependent is not generated by <em>Him</em> from <em>Himself</em>.</p>
<p>In Dualism, avidya (ignorace) is located in the dependent Jiva and does not affect the Brahman in any way. So there is no need for a concept like <em>Maya</em>.</p>
<ul>
<li>Ramanuja - all <em>Jivas</em> are same after liberation</li>
<li>Madhva - <em>Jivas</em> remain different even after liberation</li>
</ul>
<h3 id="doctrine-of-salvation">Doctrine of Salvation</h3>
<p>Unlike in some the other systems of Vedanta, Sravana and Manana are only subsidiary to Nidhidyaasana in Madhva’s system.</p>
<p><em>Why Madhvas argue so much?</em></p>
<p>A competent Guru has to give proper criticism of other opposing systems of thought, as intellectual vacillation of disciplines will not disappear otherwise. Due to this, Madhavas have been criticized for intellectual pugnacity and acrimonious attitude… According to them (Madhvas) unless systems opposed to Madhvism are criticized theradbare and their hollowness shown, one’s own faith in the true doctrine will not be unshakably established. This will no doubt engender an element of exclsiveness and fanaticism as in almost all forms of theism. (p185)</p>
<p>In Madhva’s system, scriptures hold value but experience trumps it. Even if scriptures say fire is cold, the experience is otherwise and this holds more value.</p>
<h2 id="sri-vallabha-द्वैताद्वैत-shuddhatvaita-">Sri Vallabha: द्वैताद्वैत (Shuddhatvaita )</h2>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto,w_350,h_350,c_pad/blog/vallabha.jpg" alt="vallabha" /></p>
<p><a href="https://upload.wikimedia.org/wikipedia/commons/0/02/Shri_mahaprabhuji.jpg">Source</a></p>
<p>Shuddhatvaita शुद्दत्वॆता means pure Non-dualism, purity consisting in that it does not accept Maya, a principle of illusion that has necessarily got to be conceived as outside Brahman. For, Brahman, who is Satcidananda, is truth unalloyed, and there can be no touch of illusion or falsity in Him. Maya can therefore be only His real power, producing real effects and not false appearances. This eschewal of Maya, as a principle or category of falsity, either internal or extraneous to Brahman, is the most important feature of Suddhadvaita. According to the system, the term Maya means the real power if it is conceived as within Him. If on the other hand it is conceived as outside of Him, it becomes a dual category of falsity compromising the doctrine of non-duality. p217</p>
<p>… Vallabha’s position is that Brahman Himself has manifested as the universe; but no change or transformation of any kind has come over His entity thereby. The world manifested by Him is actually there and not imagined to be there by any one because of <em>Avidya</em>. p220</p>
<p>Vallabha’s system is called ब्रह्मवाद (Brahma vaada) as opposed to Shankara’s system which is called as मायावाद (Mayavaada). In Shankara’s system, Maaya becomes more profound entity than Brahman.</p>
<p>In Vallabha’s system, scriptures are the sole authority on spiritual matters. Scriptures includes all sections of the Vedas (unlike Shankara who only accepts the Upanishads), Smriti literature like Vyaasa-sutra, Mahabharta, Gita, Pancaratra and Purana literature. In practice, <em>Bhagavata Purana</em> literature is the mainstay. p224</p>
<h3 id="akshara">Akshara</h3>
<p>Akshara is Sat-cid-ananda, with the Ananda aspect considerably concealed. he is lesser than Krishna, the Purushottama, who alone is Sat-cid-ananda in fullness. The Akshara is the Impersonal Being, with whom the Shuddadvaitin identifies the Brahman of Shankara’s system of Advaita. It is interesting to note that in Shankara’s system, the personal is the Apara Brahman (lower Brahman) and Impersonal, the Para Brahman (the Supreme Brahman). Here the tables are turned. p225</p>
<h2 id="sri-krishna-chaitanya">Sri Krishna Chaitanya</h2>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto,w_350,h_350,c_pad/blog/chaitanya.jpg" alt="Chaitanya" /></p>
<p><a href="https://www.iskconbangalore.org/blog/wp-content/uploads/2015/02/Chaitanya-Maha-Prabhu.jpg">Source</a></p>
<p>The philosophy taught by Sri Krishna Chaitanya is termed as <a href="https://www.krishna.com/info/achintya-bhedabheda-tattva">Achintya-bhedabheda</a>.</p>
<p>According to this school, Krishan is the Sat-Cid-Ananda Para-Brahman. Krishan is the Absolute Person. The indefinite awareness of anything is the first and most primitive and therefore the most peripheral, understanding of anything. When awareness becomes definite, clear and defined, then only anything is fully understood. This is true with regard to the Supreme Reality. The <em>Bhagavan</em>, the Divine Personality, clear and defined is the core of Reality, and the indefinite and unmodified Brahman can be only His peripheral brilliance.</p>
<p>The school is Inconceivable Identity-in-difference (Acintya-bhedabheda). According to this school, Shakti (power) is both identical and different from Shaktimat (powerholder). It is because of this element of difference that transformation of Sakti does not affect the Saktimat. At the same time, the element of identify makes the Supreme Reality Non-Dual even in the midst of difference. How these two contradictory features can co-exist is not attempted to be explained logically. For this reason, it is designated as Acintya - alogical or incomprehensible by thought. It means logic, which is ultimately based on sense experience, cannot bring it within its laws and it has therefore to be accepted as a fact transcending human understanding. p315</p>
<p>Generally in all other Hindu religious cults, Krishna is one of the incarnations of Vishnu, but the Bengal school of Vaishnavism makes Krishan the Godhead and Vishnu one of His emanations. p316</p>
<p>The concept of Bliss becomes meaningful only when it is a matter of self-realization or realization in an object. To speak of Brahman as Bliss in the sense that it is without sorrow, as certain philosophers do, is meaningless, because even a stone, being without sorrow, can be described as bliss in that sense. Bliss without self-awareness and awareness of others is meaningless and indistinguishable from mere inertness. So Sri Krishan, the Supreme Reality, is not only <em>Rasa</em> but also <em>Rasika</em>, the enjoyer of Bliss. p324</p>rakshayAfter listening and reading to the introductory Advaita Vednata book, Vedanta Saara, I was intrigued to understand the core teachings of the alternative schools. In his talk, Swami Sarvapriyananda had spoken about the book, Bhakti Schools of Vedanta. I was fortunate enough to find a copy and some time to read through it. Here are some quick notes from this book.Notes from Vedanta-sara by Sadananda2022-03-31T00:00:00+00:002022-03-31T00:00:00+00:00https://akshayranganath.github.io/Notes-from-Vedantasaara-Sadananda<h2 id="why-this-book">Why this book?</h2>
<p>During the Covid crisis, I took up a habit of walking regularly as an exercise. Apart from helping may stay fit, it offered me about an hour of uninterrupted time. During this period, I started listening to the talks of <a href="https://www.vedantany.org/resident-swamis/">Swami Sarvapriyananda</a>. I started by listening to his introductory talks like <a href="https://www.youtube.com/watch?v=eGKFTUuJppU">“Who am I?”</a>, based the teachings of <a href="https://www.swami-krishnananda.org/mand/Mandukya_Upanishad.pdf">Mandukya Upanishad</a>. After listening to a series of his lectures, I started to listen to the <a href="https://soundcloud.com/vedantany/sets/bhagavad-gita-swami">Bhagwad Gita series</a>. While doing so, I realized that my foundations in <em>Vedanta</em> were a bit weak and I needed a firm footing.</p>
<p>While researching about it, I came across a <a href="https://www.youtube.com/watch?v=h6FbNFjDJqk&list=PLDqahtm2vA70ccqIRFR_lipqKvxrHBRRw">lecture series on <em>Vedanta-sara</em></a>. Alternatively, you listen to the lectures on <a href="https://open.spotify.com/show/5IrDmqXhiGwwyQcIUjRhtB?si=1d1f232185bf40fb&nd=1">Spotify</a> as well.</p>
<p>The lectures are based on an introductory book on <em>Vedanta</em>. Written by <em>Sadananda</em> in the 15th century, [this book](https://en.wikipedia.org/wiki/Vedantasara_(of_Sadananda) is considered as an introductory text into the philosophy of <em>Advaita Vedanta</em>.</p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto/blog/51a9XCBoPjL._SX330_BO1%2C204%2C203%2C200_.jpg" alt="Vedanta-sara by Sadaananda" /></p>
<blockquote>
<p>Book image from <a href="https://images-na.ssl-images-amazon.com/images/I/51a9XCBoPjL._SX330_BO1,204,203,200_.jpg">Amazon</a></p>
</blockquote>
<p>In this article, I wanted to note down the main highlights as a reference for myself and for anyone who is pursuing the same.</p>
<p>If you’d like to purchase the book, the book is available on <a href="https://www.amazon.com/Vedanta-sara-Sadananda-Yogindra/dp/8175051108/ref=sr_1_1?keywords=vedantasara+of+sadananda+by+nikhilananda+swami&qid=1648751909&sprefix=vedantasara+%2Caps%2C129&sr=8-1">Amazon</a>. Generally, the Advaita teachers appear to recommend these 3 books as introductory material:</p>
<ul>
<li>Vedanta-sara of Sadananda by Sadananda Yogindra</li>
<li>Drg-Drsya-Viveka: An Inquiry Into the Nature of the Seer and the Seen by Shankara</li>
<li>Aparokshanubhuti: Or Self-Realization of Sri Sankaracharya by Shankara</li>
</ul>
<p>Generally, there is a bundled deal - so do take a look and get them together.</p>
<h2 id="notes-from-the-book">Notes from the book</h2>
<h3 id="definition-of-the-cosmic-and-individual-being">Definition of the cosmic and individual being</h3>
<table>
<thead>
<tr>
<th>Aggregate Aspect</th>
<th>Name</th>
<th>Individual Aspect</th>
<th>Name</th>
<th>Characteristic</th>
<th>Kosha</th>
<th>State (Mandukya)</th>
</tr>
</thead>
<tbody>
<tr>
<td> </td>
<td>Brahman</td>
<td> </td>
<td>Jiva (जीव)</td>
<td>Other terms</td>
<td>-</td>
<td>तुरीय</td>
</tr>
<tr>
<td>Brahman + Maya</td>
<td>Ishavara</td>
<td>Limited self + Maya</td>
<td>Praagna (प्राज्ञा)</td>
<td>Causal Body</td>
<td>आनन्दमय कोश</td>
<td>प्राज्ञा (deep sleep)</td>
</tr>
<tr>
<td>Brahman + Maya + Mind</td>
<td>Hiranyagarbha (हिरण्यगर्भ) / सूत्रात्मा / प्राण</td>
<td>Limited self + Maya + Mind</td>
<td>Taijasa/Full of light (तॆजस)</td>
<td>Subtle Body (सूक्ष्म शरीर)</td>
<td>विज्ञानमय + मनोमय + प्राणमय कोश</td>
<td>तॆजस (dreaming)</td>
</tr>
<tr>
<td>Brahman + Maya + Mind + Physical Body</td>
<td>Virat (विराट्) / वैश्वनर</td>
<td>Limited self + Maya + Mind + Physical Body</td>
<td>Vishwa (विश्व)</td>
<td>Gross Body</td>
<td>प्राणमय + अन्नमय कोश</td>
<td>विश्व (waking)</td>
</tr>
</tbody>
</table>
<p>This is a summary of all the various breakdown of the core concepts.</p>
<h4 id="general-structure-of-vedantic-progress">General structure of Vedantic Progress</h4>
<table>
<thead>
<tr>
<th>Difficulty</th>
<th>Problem</th>
<th>Solution</th>
<th>Method</th>
</tr>
</thead>
<tbody>
<tr>
<td>Hardest</td>
<td>अज्ञान (Ignorance)</td>
<td>ज्ञान (Knowledge)</td>
<td>ज्ञान योग (Path of knowldge)</td>
</tr>
<tr>
<td>Medium</td>
<td>विक्षेप (unfocused mind)</td>
<td>Focused Mind</td>
<td>उपासना (*Meditation)</td>
</tr>
<tr>
<td>Easier</td>
<td>चित्त मल (Impurity of mind)</td>
<td>चित्त शुद्धि (Purification of mind)</td>
<td>कर्म योग (Path of action)</td>
</tr>
</tbody>
</table>
<h3 id="chapter-1-preliminaries">Chapter 1: Preliminaries</h3>
<blockquote>
<p>वेदान्तो नामोपनिषत्प्रमाणं .. (para 3)</p>
</blockquote>
<p>Vedanta is the evidence of the Upanishads..
Vedanta - literally means the concluding of the philosophical portion of the Vedas</p>
<h4 id="journey-of-a-vedantin-pp-20-21">Journey of a Vedantin (pp 20-21)</h4>
<ul>
<li>Performance of the daily obligatory rites leads » acquisition of virtue;</li>
<li>Acquisition of virtue » destruction of sin</li>
<li>Destruction of sin » purification of mind</li>
<li>Purification of mind » comprehension of संसार (Samsaara) / relative existence</li>
<li>Comprehension of संसार » leads to वैराग्य/renunciation</li>
<li>वैराग्य » Desire for liberation</li>
<li>Desire for liberation » search for its means</li>
<li>Search » practice of योगा (Yoga)</li>
<li>योगा » habitual tendency of the mind to settle in the Self</li>
<li>Habit » realized knowledge of passages like तत् त्वम् असि (Thou art That)</li>
<li>Knowledge » destruction of ignorance & establishment in one’s own Self</li>
</ul>
<p>About वैराग्य (dispassion)</p>
<blockquote>
<p>A thing that has an origin cannot be permanent. Therefore dispassion should be practiced for <em>all</em> things, even for the highest that man may attain - the position of <em>Brahma</em>, which is also as impermanent as any earthy object.</p>
</blockquote>
<h4 id="6-treasures-of-mind">6 Treasures of Mind</h4>
<ol>
<li>शम - control of the mind</li>
<li>दम - restraining the external organs (ie 5 sense organs & 5 organs of action)</li>
<li>उपरति - function of mind that keeps the restrained organs from going back to the objects of the senses</li>
<li>तितिक्षा - endurance / forbearance</li>
<li>समाधाना - constant concentration of the mind</li>
<li>श्रद्धा - faith (also working faith).</li>
</ol>
<p>श्रद्धा does not mean blind faith. It is like saying, have faith in a text book until you have learnt the subject. This kind of faith.</p>
<p>With the 6 treasure arises मुमुक्षत्वं, i.e., a strong desire for liberation.</p>
<h4 id="characteristics-of-a-good-गुरु-guru">Characteristics of a good गुरु (Guru)</h4>
<ul>
<li>अकामहतत्वं - desirelessness</li>
<li>अवृजिनत्वं - sinlessness</li>
</ul>
<h3 id="chapter-2-superimposition-अध्यारोप">Chapter 2: Superimposition (अध्यारोप)</h3>
<blockquote>
<p>अध्यारोप (Adhyaropa) is the superimposition of the unreal on the real, like the false perception of a snake in a rope which is not a snake.</p>
</blockquote>
<p>Main argument from Advaitins:</p>
<blockquote>
<p>Brahman alone is real, and ignorance and the entire material phenomenon of the world which are its products are only superimposition upon Brahman.</p>
</blockquote>
<p>अवस्तु means an indescribable state i.e. which is other than existence and non-existence. अज्ञान (Agyaan) / ignorance is different from reality and unreality, as neuter is different from masculine and feminine.</p>
<blockquote>
<p>This ignorance is to be one or many according to the mode of observing it either collectively or individually. (para 35)
The collective ignorance is superior to the individual ignorance because the former is associated with Brahman and latter with जीव (Jiva).</p>
</blockquote>
<h4 id="who-is-god">Who is God?</h4>
<p>In the traditional sense, ब्रह्मन् (Brahman) + अज्ञान (Agyaan) / माया (Maya) is called as सगुण ब्रह्मन् (Saguna Brahman) or ईश्वर (Ishvara). This entity is the highest manifestation of the ब्रह्मन् (Brahman) in the phenomenon universe and hence refers to the “God”.</p>
<p>ब्रह्मन् (Brahman) is indivisible. माया (Maya) can be divided infinitely. e.g.: Sun reflected in one large lake or infinite drops of water is still ignorance. The only real thing is the sun. (from lecture)</p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto,c_fill,w_800,h_400/blog/lake-gc6e8e83dc_1920.jpg" alt="water reflection" /></p>
<blockquote>
<p>The individual ignorance, associated with it (ब्रह्मन्) is also known as the causal body on account of its being the cause of egoism, etc. and as the blissful sheath because it is full of bliss and covers like a sheath;.. knows as dreamless sleep since into it everything is dissolved.. p47</p>
</blockquote>
<p>In the waking state, the <em>Jiva</em> is cognizant of the gross objects. In the deam state, the gross objects are dissolved into the subtle, and he is aware only of the subtle. In dreamless sleep, the gorss as well as the subtle objects are absorbed into the Ultimate Cause. Therefore, the state of dremless sleep has been described as the state of ultimate absorption or dissolution (प्रलय). p48</p>
<p>Individual <em>Jiva’s</em> dreamless sleep is called <em>sushuptih (सुषुप्ति:)</em> while the dreamless sleep of the One is called <em>pralaya (प्रलय )</em>.</p>
<h4 id="mahavakyaa-of-advaita-vedanta">Mahavakyaa of Advaita Vedanta</h4>
<ul>
<li>तत् त्वम् असि - “Thou art that”</li>
<li>अयम् आत्मा ब्रह्म - “This self is Brahman”</li>
<li>प्रज्ञानं ब्रह्म - “Consciousness is Brahman”</li>
<li>अहं ब्रह्मास्मि - “I am Brahman”</li>
</ul>
<h4 id="आवरण-विक्षेप-projectionconcealment">आवरण विक्षेप (Projection/Concealment)</h4>
<p>Maya / Ignorance has 2 powers:</p>
<ul>
<li>power of concealment (आवरण)</li>
<li>power of projection (विक्षेप)</li>
</ul>
<p>Just as a small cloud can obstruct the view of the sun over many miles, ignorance can conceal the true Self which is unlimited and not subject to transmigration.</p>
<blockquote>
<p>The Self covered by this (concealing power of ignorace) may become subject to <em>Samsaara (संसार)</em> (relative existence) characterised by one’s feeling sa the agent (i.e. the doer), the experiencing subject, happy, miserable, etc., just as a rope may become a snake due to the concealing power of one’s own ignorance.</p>
</blockquote>
<blockquote>
<p>The power of projection creates all frm the subtle bodies to the cosmos.</p>
</blockquote>
<p>Ignorance endowed with these twin powers of concealment and projection is the cause which transforms, as it were, the Pure Self, immutable, unattached and indivisible, into the <em>Jiva</em> and the world. As ignorace regarding teh rope gives rise to the illution of the snake, similarly ignorace regarding the Self, by its power of projection, brings before our mind the illusion of the phenomenol universe.</p>
<p><em>Material vs Efficient cause</em></p>
<ul>
<li>Efficient cause: Potter making his pot (ie creator and created are seperate)</li>
<li>Material cause: Milk turning into curd (creator transforms into created)</li>
</ul>
<p>Is <em>Brahman</em> the material or efficient cause of the Universe?</p>
<ul>
<li>Brahman is not the efficient cause. _Having projected it, he entered it” (Tait. Up.)</li>
<li>Brahman is not the material cause. If it were, the cause and effect would be same and hence unreal.</li>
<li>Brahman+Maya from His Consciousness aspect is the efficient or instrumental cause.</li>
<li>Brahman when looked upon his <em>Upadhi</em> aspect is the material cause of the Universe.</li>
</ul>
<p>Therefore, a new idea विवर्ता (Vivarta) is introduced. Law of <em>Vivarta</em> means the the transformation of the caue into effect without the former losing its own character i.e., the wholevisible universe is a mere illusionary appearance - while Brahman is the only real entity. For example, a spider is the efficient and material cause of the spider web.</p>
<p>Law of <em>Vivara</em> is different from law of <em>परिणाम</em> (evolution) which admits real change to the cause.</p>
<h4 id="evolution-of-5-elements">Evolution of 5 elements</h4>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto,w_650,e_sharpen/blog/vedantasara-5-elements.png" alt="5 elements" />
(para 57)</p>
<p>These are called as सूक्ष्म भूतानि (i.e., pure elements). The same elements when compounded in specific proportions become the स्थूल भूतानि (i.e., gross elements).</p>
<h3 id="nature-of-subtle-bodies">Nature of Subtle Bodies</h3>
<p>At this point, we’re talking about the internal organs, brain and mind.</p>
<p>लिङ्ग शरीर have 17 parts:</p>
<ul>
<li>Intellect & Mind (बुद्धि and मनस्)</li>
<li>5 organs of perception / ज्ञानेन्द्रियाणि (ears, skin, eyes, tongue and nose)</li>
<li>5 organs of action / कर्मेन्द्रियाणि (speech, hands, feet, organs of evacuation and generation).</li>
<li>5 vital forces / प्राण are प्राण, अपान, व्यान, उदान, समान</li>
</ul>
<p><em>Subtle Body</em></p>
<p>The intellect & mind are split into 4 parts. All are considered as अन्तःकरण (i.e., modification of internal instrument)</p>
<ul>
<li>बुद्धि (Intellect) is that modification of internal instrument that <em>determines</em>.</li>
<li>चित्त (mind stuff / memory) is the modification of internal instrument that remembers. Considered part of बुद्धि.</li>
<li>मनस् is that modification internal instrument that <em>considers pros and cons</em> (संकल्प विकल्प).</li>
<li>अहङ्कार (ego) is the modification of internal instrument that appropriates to itself (makes it <em>mine</em>). Considered part of मनस्</li>
</ul>
<table>
<thead>
<tr>
<th>Inner Instrument</th>
<th>Organs</th>
<th>Sheath</th>
<th>Main feature</th>
</tr>
</thead>
<tbody>
<tr>
<td>बुद्धि</td>
<td>5 Organs of perception</td>
<td>विज्ञानमय कोश ==> जीव which transmigrates</td>
<td>सत्त्व</td>
</tr>
<tr>
<td>मनस्</td>
<td>5 Organs of perception</td>
<td>मनोमय कोश</td>
<td>सत्त्व</td>
</tr>
<tr>
<td>-</td>
<td>5 Organs of action + 5 vital forces</td>
<td>प्राणमय कोश</td>
<td>रजस</td>
</tr>
</tbody>
</table>
<h3 id="evolution-of-universe">Evolution of Universe</h3>
<p>From the 5 pure elements, using the concept of पन्चिकरणम् (mixing in 5ths), the 5 compounded elements are produced. These 5 compounded <em>gross</em> elements are also <em>Aakaasha</em> (ie ether), air, fire, water and earth.</p>
<p>Each element manifests the following:</p>
<table>
<thead>
<tr>
<th>Element</th>
<th>Sense</th>
<th>Sense</th>
<th>Sense</th>
<th>Sense</th>
<th>Sense</th>
</tr>
</thead>
<tbody>
<tr>
<td>Ether</td>
<td>Sound</td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td>Air</td>
<td>Sound</td>
<td>Touch</td>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td>Fire</td>
<td>Sound</td>
<td>Touch</td>
<td>Form</td>
<td> </td>
<td> </td>
</tr>
<tr>
<td>Water</td>
<td>Sound</td>
<td>Touch</td>
<td>Form</td>
<td>Taste</td>
<td> </td>
</tr>
<tr>
<td>Earth</td>
<td>Sound</td>
<td>Touch</td>
<td>Form</td>
<td>Taste</td>
<td>Smell</td>
</tr>
</tbody>
</table>
<p>From the 5 compounded elements, the following worlds (लोक) have evolved:</p>
<ul>
<li>7 higher worlds / planes: भूवर स्वर महर जन तप सत्यं</li>
<li>7 nether worlds: अतल वितल सुतल रसातल महातल पाताल</li>
<li>The world (ie earth)</li>
<li>4 kind of gross bodies along with food and drink appropriate for them.</li>
</ul>
<p>4 kinds of gross bodies or organisms are those born of</p>
<ol>
<li>womb (humans, higher animals)</li>
<li>egg (birds, reptiles)</li>
<li>moisture (lice, mosquitos)</li>
<li>soil (trees, plants)</li>
</ol>
<p>Aggregate of all gross bodies is called <em>वैश्वनर</em>/<em>विराट्</em>. Individual is called <em>विश्व</em>. The gross body is also called अन्नमय कोश.</p>
<p>The organs of action and perception and mind are controlled by a corresponding god.</p>
<ul>
<li>5 organs of perception - दिक् वायु सूर्य वरुण अश्विन</li>
<li>5 organs of action - अग्नि इन्द्र विष्णु यम प्रजापति</li>
<li>4 inner organs - चन्द्र (conscious mind), विष्णु (subconscious mind), ब्रह्म (intellect) शिव (ego)</li>
</ul>
<h2 id="overview-of-philosophical-schools">Overview of Philosophical Schools</h2>
<p>In olden India, any debate or argument has to have 3 parts:</p>
<ul>
<li>श्रुति - evidence from scripture</li>
<li>युक्ति - reasoning / inference</li>
<li>अनुभूति - experience / direct perception</li>
</ul>
<p>चारवाका (Chaaravaaka) / Materialists were atheists who believe in the physical body or physical world and do not believe in the existence of any higher order being.</p>
<table>
<thead>
<tr>
<th>Philosophy</th>
<th>Evidence</th>
</tr>
</thead>
<tbody>
<tr>
<td>Deluded Layman</td>
<td>Children are the self</td>
</tr>
<tr>
<td>चारवाका (Materialists) - level 1</td>
<td>Physical body is the self</td>
</tr>
<tr>
<td>चारवाका (Materialists) - level 2</td>
<td>Sense organs are the self</td>
</tr>
<tr>
<td>चारवाका (Materialists) - level 3</td>
<td>प्राणा / life forces are the self</td>
</tr>
<tr>
<td>चारवाका (Materialists) - level 4</td>
<td>मनस् / mind is the self</td>
</tr>
<tr>
<td>योगाचारा / हिनायना Teraavada Buddhists</td>
<td>“self” is a stream of consciousness. Followed in Sri Lanka, Thailand</td>
</tr>
<tr>
<td>Mimaamsaka न्याय / वैशेषिक (तार्किक / प्रभाकर )</td>
<td>Ignorance is the self</td>
</tr>
<tr>
<td>Mimaamsaka Bhatta’s School</td>
<td>Consciousness associated with ignorance is the self</td>
</tr>
<tr>
<td>शून्यवादि (माध्यमिक शून्यवाद) Maadhyamika Shoonyavada / Nihilistic School of Buddhism</td>
<td>Self is identified with void. Followed in Tibet.</td>
</tr>
<tr>
<td>अद्वैत Advaita</td>
<td>True self is the Brahman</td>
</tr>
</tbody>
</table>
<ul>
<li>योगाचार (Yogachaara) Buddhism was based on the original teachings of Buddha.</li>
<li>माध्यमिक शून्यवाद (Nihilistic school) is based on extrapolation of Buddha’s teachings. नागार्जुन (Nagarjuna) was the titan who formulated the philosophical foundation for this school.</li>
<li>कुमारिल भट्ट (Kumarila Bhatta) laid foundation of <a href="https://www.mimamsa.org/authors/kumarila_bhatta.html">Bhatta</a> school of philosophy. He systematically argued against the Buddhist traditions and laid the foundation for शंकर (Shankara) and other Hindu teachers.</li>
<li>प्रभाकर Prabhaakara Bhatta was the student of Kumarila Bhatta. However, he argued against his teacher and hence his school is called Guru and his school is called <a href="https://www.mimamsa.org/authors/prabhakara_mishra.html">गुरुवाद</a>.</li>
</ul>
<p>The hardest challenge to Advaita historically has been from the Shoonyavaada.</p>
<blockquote>
<p>As the Self is too subltle for ordinary understanding, the passages in question gradually train the mind to dwell on finer and finer aspects of the Self. This is called the अरुन्धती न्याय (Arundhati Nyaaya). One wishing to locate the tiny star called <em>Arundhati</em> is first directed to look at bigger and brighter stars. Gradually he comes to the right star. Similarly those scriptual passages gradually help one on to the Reality.</p>
</blockquote>
<p>## अपवाद / De-Superimposition</p>
<blockquote>
<p>As a snake falsely perceived in a rope is ultimately found out to be nothing but the rope: similarly the world of unreal things, beginning with ignorance, superimposed upon he Reality, is realized, at the end, to be nothing but the Brahman.This is known as de-superimpostion (<em>Apavada</em>). p101</p>
</blockquote>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto,w_650/blog/thumbnail-mirage.jpg" alt="mirage" /></p>
<p>In other words, Brahman through illusion appears as the phenomenal world. The breaking up of this illusion - which consists only of name and form - and the consequent discovery of Brahman, which is the underlying reality, is called <em>apavada</em>.</p>
<p><em>विवर्ता</em> / <em>Vivarta</em> means an apparent modification or illusion which is caused by ignorance. <em>विकारा</em> / <em>Vikaara</em> on the other hand is actual transformation like milk to curd.</p>
<p>As a snake is a विवर्ता of a rope, so is the world the विवर्ता of Brahman and the illusion is removed by Knowledge.</p>
<p>Advaita believes the world is a <em>विवर्ता</em> of the Brahman. <em>विषिठद्वैत</em> / <em>Qualified monoism</em> believes the world to be a <em>विकारा</em> of the Brahman.</p>
<h3 id="तत्त्वमसि">तत्त्वमसि</h3>
<h4 id="defining-तत्--tat">Defining तत् / Tat</h4>
<p>In the sentence, <em>तत्त्वमसि</em>, the word तत् has 3 meanings:</p>
<ul>
<li>वाच्य / primary meaning = विराट्</li>
<li>लक्ष्य / secondary or implied = हिरण्यगर्भ</li>
<li>व्यक्त / suggested = ईश्वर</li>
</ul>
<p>In Sanskrit Grammar, there are 3 kinds of sentences:</p>
<ul>
<li>सामानाधिकरण्य / Saamaanaadhikaranya: similarity, i.e. 2 words have the same substratum</li>
<li>विशेषण विशेष्य भाव / Visheshana-visheshyabhaava: adjectival relationship i.e. words qualify each other</li>
<li>लक्ष्य लक्षण भाव / Lakshya-lakshana bhaava: implied meaning, i.e. 2 words that imply something</li>
</ul>
<table>
<thead>
<tr>
<th>Relationship</th>
<th>सोऽयं देवदत्तः</th>
<th>तत्त्वमसि</th>
</tr>
</thead>
<tbody>
<tr>
<td>सामानाधिकरण्य</td>
<td>“This” and “that” is associated with Devadutta in the past and present. Yet, both refer to the same person.</td>
<td>“That” is Consciousness characterized by remoteness while “Thou” is Consciousness characterized by immediacy. Yet, both refer to the same thing.</td>
</tr>
<tr>
<td>विशेषण विशेष्य भाव</td>
<td>“This” and “that” are about present and past implying a contradiction and yet, they qualify each other.</td>
<td>Similarly, “That” and “Thou” are contradictory and yet qualify each other.</td>
</tr>
<tr>
<td>लक्ष्य लक्षण भाव</td>
<td>“This” and “That” by elimination of contraction positions of past and present, stand in relation of implier and implied with Devadutta who is common to both.</td>
<td>“That” and “Thou” by elimination of remoteness and immediacy etc. stand in relation of implier and implied with Consciousness which is common to both.</td>
</tr>
</tbody>
</table>
<p>3 kinds of लक्ष्य लक्षण भाव:</p>
<ul>
<li>
<p><em>Jahallakshana</em> where the direct meaning is discarded in favor of the implied meaning. e.g.: गङ्गायां घोषः, i.e. “The village of the cowherds is in the Ganga”. Here the direct meaning “in the Ganga” is discarded in favor of “on the Ganga”.</p>
</li>
<li>
<p><em>Ajahallakshana</em> where the direct meaning is not fully discarded but hints at the real meaning. शोणः धावति, i.e., the “red color is running”. We get the meaning as a red colored horse is running.</p>
</li>
<li>
<p><em>Jahadajahakkshana</em> where one part of the direct meaning of a sentence is given up and another part is retained. e.g. In the sentence “This is that Devadutta”, the associations regarding time and place is discarded but the person called Devadutta is accepted. Similarly in तत्त्वमसि, the contradictory factors of remoteness and immediacy, omniscience and partial knowledge associated with “That” and “Thou” are discarded and Pure Consciousness which is common in both is accepted.</p>
</li>
</ul>
<h4 id="चित्तवृत्ति--फलवृत्ति">चित्तवृत्ति / फलवृत्ति</h4>
<p>चित्तवृत्ति (Chitta Vrutti) is the focussing of the mind. It is like using a torch to shine light on a specific object in a dark room.</p>
<p>फलवृत्ति (Phalavutti) is the understanding / perception or recognition of an object in the mind.</p>
<p>In the spiritual journey, we need चित्तवृत्ति. For example, moonlight is reflected sunlight. At night, it helps illuminate and we “see”. During the solar eclipse, the moon reflects back the sun light. We don’t really need this light - the sun is self illumined. So, we need to focus our mind but, not necessarily aim for “recognition” of Brahman as there is no “knowledge of Brahman” as Brahman is all knowledge.</p>
<h2 id="steps-to-self-realization">Steps to Self-Realization</h2>
<p>In the 10th man story (दशमस्त्वामसि),</p>
<ul>
<li>The 10th man was always present. This is the <em>direct knowledge</em>. However, the person wasn’t “aware” of it.</li>
<li>Somebody came and pointed out and the person realized, “Oh! I am the 10th man” This is the <em>indirect knowledge</em>.</li>
</ul>
<p>4 fold path to self-realization:</p>
<p>श्रवण > मनन > निधिद्यासन leading to निर्विकल्प समाधि</p>
<ul>
<li>श्रवण (shravaNa) means reading, hearing and actually understanding</li>
<li>मनन (manana) / reasoning means fitting things, understanding and “getting it”</li>
<li>निधिद्यासन (nidhidhyaasana) staying with the thought of <em>Brahman</em>, ie <em>Vedic meditation</em>.</li>
</ul>
<p>Algorithm to judge good work - qualities of a good article, essay or any good written work the beginning, the conclusion, repetition, originality, result, eulogy and demonstration.</p>
<p>Example of “good” work is <em>Chandogya Upanishad</em>.</p>
<h2 id="the-steps-to-self-realization">The Steps to Self-Realization</h2>
<p>8 fold path to निर्विकल्प समाधि (Nirvikalpa Samadhi):</p>
<ul>
<li>यम (Yama) consists of non-injury, truthfulness, non-stealing, continence and non-acceptance of gifts.</li>
<li>नियम (Niyama) cleanliness, austerity, study including self-study</li>
<li>आसन (Aasana)</li>
<li>प्राणायाम (Praanayaama) control of vital forces</li>
<li>प्रत्याहार withdrawing sense organs from their respective objects</li>
<li>धारण (Dhaarana) concentration / fixing of mind on Brahman</li>
<li>ध्यान (Dhyaana) / meditation. When mind wanders, gently bring it back to focus.</li>
<li>समाधि (Samadhi) Savikalpa samaadhi leading to nirvikalpa samaadhi.</li>
</ul>
<p><em>4 Obstacles to निर्विकल्प समाधि</em></p>
<ul>
<li>लय / torpidity: lapsing into sleep</li>
<li>विक्षेप / distraction: unable to focus on Brahman</li>
<li>कषाय: / attachment: lurking desire for wordly things</li>
<li>रसावाद / enjoyment: Tasting the bliss of सविकल्प समाधि and not wanting to progress any further.</li>
</ul>rakshayWhy this book?रथसम्प्तम्याः महत्त्वं किं - इकः लघु तिप्पणि2022-02-07T00:00:00+00:002022-02-07T00:00:00+00:00https://akshayranganath.github.io/%E0%A4%B0%E0%A4%A5%E0%A4%B8%E0%A4%AE%E0%A5%8D%E0%A4%AA%E0%A5%8D%E0%A4%A4%E0%A4%AE%E0%A5%8D%E0%A4%AF%E0%A4%BE%E0%A4%83%20%E0%A4%AE%E0%A4%B9%E0%A4%A4%E0%A5%8D%E0%A4%A4%E0%A5%8D%E0%A4%B5%E0%A4%82<p>अध्य - सोमवासरः ७ Febuary मासे रथ सप्तमी इति त्योहारः। माघमासय्स सप्ततम दिने सॊर्यदेवस्य जन्मदिनं इति विश्वासः। रथसप्तम्यां भक्ताः सूर्यस्य पूजा कुर्वन्ति। आदित्यहृदयं तथा अन्य मन्त्राः जपन्ति।</p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto/blog/Ras-1024x569.jpg" alt="Surya Devata" /></p>
<p>हिन्दुधर्मस्य अनुसारेण सूर्यदेवः तस्य रथस्य उपरि आकाशात् भ्रमणं करोति। रथस्य सारथि सूर्यस्य अनुजः अस्ति। तस्य नामः अरुणः। रथस्य द्वादशः चक्रा: सन्ति। ते वर्षस्य मासान् सूचयन्ति। रथस्य कर्षणं सप्त अश्वाः कुर्वन्ति। ते सप्ताहस्य सप्त दिनानि सूचयन्ति। सप्त अश्वाः इन्द्रधनुषस्य सप्त रङ्गानि अपि सूचयन्ति इति भिन्नाभिप्रायं।</p>
<p>Image source: <a href="https://mrst1.latestly.com/wp-content/uploads/2020/01/Ras-1024x569.jpg">https://mrst1.latestly.com/wp-content/uploads/2020/01/Ras-1024x569.jpg</a></p>rakshayअध्य - सोमवासरः ७ Febuary मासे रथ सप्तमी इति त्योहारः। माघमासय्स सप्ततम दिने सॊर्यदेवस्य जन्मदिनं इति विश्वासः। रथसप्तम्यां भक्ताः सूर्यस्य पूजा कुर्वन्ति। आदित्यहृदयं तथा अन्य मन्त्राः जपन्ति।बिलिगिरि रङ्गनाथस्य देवालयस्य कथा2021-11-02T00:00:00+00:002021-11-02T00:00:00+00:00https://akshayranganath.github.io/%E0%A4%AC%E0%A4%BF%E0%A4%B2%E0%A4%BF%E0%A4%97%E0%A4%BF%E0%A4%B0%E0%A4%BF-%E0%A4%B0%E0%A4%99%E0%A5%8D%E0%A4%97%E0%A4%A8%E0%A4%BE%E0%A4%A5%E0%A4%B8%E0%A5%8D%E0%A4%AF-%E0%A4%A6%E0%A5%87%E0%A4%B5%E0%A4%BE%E0%A4%B2%E0%A4%AF%E0%A4%B8%E0%A5%8D%E0%A4%AF-%E0%A4%95%E0%A4%A5%E0%A4%BE<p>अस्माकं कुलदॆवता बिलिगिरि रङ्गनाथ:। बिलिगिरि इति पर्वत: अस्ति। पर्वत: मॆसूरू नगरानत् समन्तात् १०० किमि दूरात् अस्ति। देवालय: बहू प्राचीन: अस्ति। एका कथा अपि प्रसिद्धा अस्ति।</p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/w_650,h_650,f_auto,q_auto/blog/1200px-Ancient_Biligiri_Ranganatha_Temple.jpg" alt="teample vide" /></p>
<p>पुरातन काले वसिष्ट: मुनि: एतत् पर्वते वेङ्कटेश्वर स्वम्ये: क्रुते तप: क्रुतवान्। वेङ्कटेश्वर स्वामि: सन्तुष्ट: अभवत्। स्वामि: मुनिम् आशीर्वदितवान्। तत् प्रसङ्गस्य स्मरणार्थं वसिष्ट मुनि: देवालयस्य निर्माणं क्रुतवान्। देवालये वेङ्कटेश्वर स्वम्ये: मूर्ति: अपि स्थापितवान्।</p>
<p>रामयण काले श्रीराम: च लक्ष्मण: अपि सीताया: अन्वेशणां क्रुत्वा अत्र आगत्य स्वामिं पूजितॊ स्म इति विश्वास:।</p>
<p>गत वर्शे देवालयस्य पुनर्निमाणस्य कर्यं आरम्भम् अभवत् इति वर्ता श्रुतवन्त:। आगामि ग्रीश्म काले यदा वयं भरत देशं गमिश्याम: तदा बिलिगिरि रङ्गनाथ स्वम्ये: दर्शनम् आवश्यकं कुर्म: इति योजना ।</p>rakshayअस्माकं कुलदॆवता बिलिगिरि रङ्गनाथ:। बिलिगिरि इति पर्वत: अस्ति। पर्वत: मॆसूरू नगरानत् समन्तात् १०० किमि दूरात् अस्ति। देवालय: बहू प्राचीन: अस्ति। एका कथा अपि प्रसिद्धा अस्ति।Getting Started with Python and DynamoDB2021-09-01T00:00:00+00:002021-09-01T00:00:00+00:00https://akshayranganath.github.io/Python-And-DynamoDb<p>Recently, I was working on a problem that needed me to store a few GB of data. This was too much for a CSV file and I was looking at alternatives. Although I had read about <a href="https://en.wikipedia.org/wiki/NoSQL">NoSQL</a> and <a href="https://aws.amazon.com/dynamodb/">DynamoDB</a> before, I had never used it. Since I now had a use case, I thought of giving it a try.</p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/w_600,h_400,f_auto,q_auto,dpr_1.5/blog/pexels-photo-169573.jpg" alt="coding" /></p>
<p>While trying to work with DynamoDB and Python, I realized that the typical getting started video or documents focus a lot on the very specific task. For example, they may show you how to create a table using the UI with no explanation on how to create a table. I wanted to take a more holistic approach. I did not discover everything - so I’ll be linking to the full article that I referenced while I was building my solution.</p>
<h2 id="use-case">Use Case</h2>
<p>I work as a Solutions Architect at <a href="https://cloudinary.com/">Cloudinary</a>. I was on a project that required us to analyze a very large set (think millions) of images. The end goal was to run the images through an algorithm that can extract the text content (if any) and store it in some location. Once done, the text would be mined for certain patterns that was related to a customer’s use case.</p>
<p>For this purpose, I wanted to use the following:</p>
<ul>
<li><a href="https://cloudinary.com/documentation/ocr_text_detection_and_extraction_addon">Cloudinary’s OCR add-on</a> module for text extraction.</li>
<li><a href="https://cloudinary.com/documentation/admin_api#update_details_of_an_existing_resource">Admin API</a> to enable the add-on. I needed to do this since the images had already been uploaded to Cloudinary.</li>
<li>Lastly, DynamoDB to store the mapping of the image and the text extracted from the image.</li>
</ul>
<h2 id="why-dynamodb">Why DynamoDB?</h2>
<p>I had read about this database while preparing for my certification exams. Apart from that, I had never used it. So I thought this would be a great opportunity to try it out. When I tested it out, the setup was simple and working with Python was a breeze. If I had to work with MySQL, it would have required me to setup a database, a table and identified the different column types up-front. Auto-scaling and cost too would have been higher if I had opted for this approach.</p>
<p>I liked the simplicity of the setup. When creating a new database, all you have to specify is the <em>partition key</em> which is similar to the <em>primary key</em> of a SQL database. Apart from that, pretty much everything else is optional. Since I was testing this out, I started with the default settings and added the primary key as <code class="language-plaintext highlighter-rouge">public_id</code>. This is basically the image file URI (ie, the file path+file name on Cloudinary). For my setup, AWS said I would be charged a princely sum of $ 0.78 per month! Of course, this wouldn’t not hold true once I pumped in the data but, it was re-assuring that this was not an expensive solution.</p>
<h2 id="how-to-work-with-dynamodb">How to work with DynamoDB?</h2>
<h3 id="basic-crud-operations">Basic CRUD Operations</h3>
<p>Just like most novices, my learning started with Google search. However, most search lead me to AWS documentation. Although it is very informative, it is very wordy. I wanted to jump straight to the point where I could make a call to retrieve and add new rows to my table. I found a video by <a href="https://www.youtube.com/watch?v=Al1xwYhQ-BM">soumilshah1995</a> on Youtube that did a great job. He shows the typical create-read-update-delete (CRUD) operations with DynamoDB. He has also helpfully published the code as a <a href="https://github.com/soumilshah1995/Learn-AWS-with-Python-Boto-3/blob/master/Youtube%20DynamoDB.ipynb">Jupyter notebook</a>.</p>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto,w_350,h_250,e_unsharp_mask/blog/soumilshah1995.png" alt="soumil shah" /></p>
<h3 id="query-vs-scan">Query vs Scan</h3>
<p>The next thing to understand is the concept of a scan vs a query. A query is where you can specify a specific criteria based on the primary key while a scan basically reads and compares against all rows of the table. Unlike regular SQL, DynamoDB can support duplicate <code class="language-plaintext highlighter-rouge">partition key</code>. However, in my case this wouldn’t work. I would be getting text from images and each image had a unique URI. So, I would have to end up running table scans.</p>
<p>However, if you are interested to understand this more, <a href="https://stackoverflow.com/questions/43452219/what-is-the-difference-between-scan-and-query-in-dynamodb-when-use-scan-query">StackOverFlow</a> has an excellent article. While exploring this, I ran into the concepts of <a href="https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-indexes-general.html"><em>Global Secondary Index</em> and <em>Local Secondary Index</em></a>. I did not need this since my data would be used for limited period of time. Not using the indices would also save some cost at the expense of not offering performant querying capabilities.</p>
<h2 id="code-solution">Code Solution</h2>
<p>Here’s my final solution. I pulled up a list of images that needed to be processed. To get list of images on an account, you can use either the <a href="https://cloudinary.com/documentation/admin_api#get_resources">Admin API’s resource method</a> or the <a href="https://cloudinary.com/documentation/search_api">Search</a> method. I loop over the list and enable OCR for each image. Since images were already uploaded, I had to use the <a href="https://cloudinary.com/documentation/admin_api#update_details_of_an_existing_resource">Admin API’s Update</a> mechanism. Note that this call has rate limits. So I had to add additional logic to ensure that my multi-threaded code remained within the rate limit. You can check my blog on <a href="https://akshayranganath.github.io/Rate-Limiting-With-Python/">rate limiting in Python</a> to see this in action.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">cloudinary.api</span>
<span class="n">resp</span> <span class="o">=</span> <span class="n">cloudinary</span><span class="p">.</span><span class="n">api</span><span class="p">.</span><span class="n">update</span><span class="p">(</span>
<span class="n">resource</span><span class="p">,</span>
<span class="n">ocr</span><span class="o">=</span><span class="s">"adv_ocr"</span>
<span class="p">)</span>
</code></pre></div></div>
<p>From the response, I had to extract the field that held the text information. The OCR plugin first shows a summary of all the text followed by each text element and its bounding box. I just needed the summary. Here’s how this would work.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">ocr_info</span> <span class="o">=</span> <span class="n">resp</span><span class="p">[</span><span class="s">'info'</span><span class="p">][</span><span class="s">'ocr'</span><span class="p">][</span><span class="s">'adv_ocr'</span><span class="p">]</span>
<span class="k">if</span> <span class="n">ocr_info</span><span class="p">[</span><span class="s">'status'</span><span class="p">]</span> <span class="o">==</span> <span class="s">"complete"</span><span class="p">:</span>
<span class="k">if</span> <span class="s">'data'</span> <span class="ow">in</span> <span class="n">ocr_info</span><span class="p">:</span>
<span class="n">text_data</span> <span class="o">=</span> <span class="n">ocr_info</span><span class="p">[</span><span class="s">'data'</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span>
<span class="k">if</span> <span class="s">'textAnnotations'</span> <span class="ow">in</span> <span class="n">text_data</span> <span class="ow">and</span> <span class="nb">len</span><span class="p">(</span><span class="n">text_data</span><span class="p">[</span><span class="s">'textAnnotations'</span><span class="p">])</span> <span class="o">></span> <span class="mi">0</span> <span class="ow">and</span> <span class="s">'description'</span> <span class="ow">in</span> <span class="n">text_data</span><span class="p">[</span><span class="s">'textAnnotations'</span><span class="p">][</span><span class="mi">0</span><span class="p">]:</span>
<span class="n">text</span> <span class="o">=</span> <span class="n">text_data</span><span class="p">[</span><span class="s">'textAnnotations'</span><span class="p">][</span><span class="mi">0</span><span class="p">][</span><span class="s">'description'</span><span class="p">]</span>
</code></pre></div></div>
<p>If you want to try on terminal, you can save the output from enable OCR to a JSON file and run a <a href="https://stedolan.github.io/jq/">jq</a> query as follows:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cat ocr.json| jq '.info.ocr.adv_ocr.data[0].textAnnotations[0].description'
</code></pre></div></div>
<p>Finally, I had to update the database.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">boto3</span>
<span class="k">def</span> <span class="nf">update_db</span><span class="p">(</span><span class="n">public_id</span><span class="p">,</span> <span class="n">text</span> <span class="o">=</span> <span class="bp">None</span><span class="p">):</span> <span class="c1"># removed other fields not relevant to blog post
</span> <span class="k">try</span><span class="p">:</span>
<span class="n">table</span><span class="p">.</span><span class="n">put_item</span><span class="p">(</span><span class="n">Item</span><span class="o">=</span><span class="p">{</span>
<span class="s">'publicId'</span><span class="p">:</span> <span class="n">public_id</span><span class="p">,</span>
<span class="s">'text'</span><span class="p">:</span> <span class="n">text</span>
<span class="c1"># .. other fields not relevant for this blog.. #
</span> <span class="p">})</span>
</code></pre></div></div>
<p>With this code, I was able to extract the OCR text and push it to a DynamoDB. Once this process completes, I plan to run some queries and extract the data as a CSV for long term storage.</p>
<h3 id="gotchas">Gotchas</h3>
<p>While working with the use-case, I ran into a few issues and I thought of documenting them.</p>
<ul>
<li>Size restrictions: AWS imposes size limits on the primary key and composite keys. The limits are 1024 and 2048 bytes respectively. (<a href="https://stackoverflow.com/questions/38557528/is-there-a-size-limit-on-partition-part-of-a-composite-primary-key-in-aws-dynamo">Source</a>) If you don’t consider this, inserts to database fill fail with the following error. Unfortunately, you can’t change the keys once the table has been created.</li>
</ul>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>botocore.exceptions.ClientError: An error occurred (ValidationException) when calling the PutItem operation: One or more parameter values were invalid: Aggregated size of all range keys has exceeded the size limit of 1024 bytes
</code></pre></div></div>
<ul>
<li>Concurrency restrictions: You are constrained by the read and write capacity that is provisioned with the database. If you set it to be too low, you will see as below. To fix it, you will need to start increasing the write (or read) capacity for your database.</li>
</ul>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>An error occurred (ProvisionedThroughputExceededException) when calling the PutItem operation (reached max retries: 9): The level of configured provisioned throughput for the table was exceeded. Consider increasing your provisioning level with the UpdateTable API.
</code></pre></div></div>
<ul>
<li>Working with Index: I thought using an index would be fun. So I created one for the table. However, I kept getting the error <code class="language-plaintext highlighter-rouge">Cannot read from backfilling global secondary index</code>. According to <a href="https://stackoverflow.com/questions/59322281/com-amazonaws-services-dynamodbv2-model-amazondynamodbexception-cannot-read-fro">StackOverflow</a>, the error is supposed to go away within a few minutes. However, I saw this error even after 1 day after the last update to my database. So I simply ignored the index.</li>
</ul>
<p>Hope you find this useful and try to take DynamoDB for a spin yourself!</p>rakshayRecently, I was working on a problem that needed me to store a few GB of data. This was too much for a CSV file and I was looking at alternatives. Although I had read about NoSQL and DynamoDB before, I had never used it. Since I now had a use case, I thought of giving it a try.Rate Limiting with Python2021-08-17T00:00:00+00:002021-08-17T00:00:00+00:00https://akshayranganath.github.io/Rate-Limiting-With-Python<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto,g_auto,w_600,h_400,c_crop/blog/speed-3394370_1280.jpg" alt="man zooming on a scotter" /></p>
<p><a href="https://cdn.pixabay.com/photo/2018/05/12/19/16/speed-3394370_1280.jpg">Source</a></p>
<p>As programmers, we come across a variety of APIs that have some restrictions. Rate Limiting is one such constraint that is implemented to ensure that the system offering the service can actually accept and process the requests. According to <em>Wikipedia</em>, <a href="https://en.wikipedia.org/wiki/Rate_limiting">Rate Limiting</a> is a feature of computer networks which is used to</p>
<blockquote>
<p>control the rate of requests sent or received by a network interface controller. It can be used to prevent DoS attacks[1] and limit web scraping.</p>
</blockquote>
<p>Whenever rate limits are enforced, the limit are generally documented. For example, <a href="https://openweathermap.org/price">OpenWeatherMap’s pricing</a> page has the following limits on the free tier:</p>
<ul>
<li>60 calls / minute</li>
<li>1,000,000 calls / month</li>
</ul>
<p><img src="https://akshayranganath-res.cloudinary.com/image/upload/f_auto,q_auto,w_600,e_unsharp_mask/blog/weather-rate-limits.png" alt="pricing" /></p>
<p>At 60 calls/minute, we could end up consuming the monthly quota in about 11.5 days. So the actual rate limit to remain within the monthly quota would be 1,000,000/ (30 days * 24 hours/day * 60 minutes/day) = 23 calls / minute. The question is how do you ensure that your code remain within this rate limit? Moreover, if you have multi-threaded program, you would need to ensure that the rate limit applies across the threads and the counter for request is thread-safe. Let’s take a look at this example. If you’d like to explore API rate limiting in details, please refer to <a href="https://nordicapis.com/everything-you-need-to-know-about-api-rate-limiting/">this blog post</a>.</p>
<h2 id="python-ratelimiter">Python Ratelimiter</h2>
<p>One of the libraries that can help implement rate limits in Python is <em><a href="https://pypi.org/project/ratelimiter/">ratelimiter</a></em>. The rate limiting functionality can be implemented using a few mechanisms as explained on the library page. In my case, I was interested in the <em>decorater</em> approach.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">ratelimiter</span> <span class="kn">import</span> <span class="n">RateLimiter</span>
<span class="o">@</span><span class="n">RateLimiter</span><span class="p">(</span><span class="n">max_calls</span><span class="o">=</span><span class="mi">10</span><span class="p">,</span> <span class="n">period</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">do_something</span><span class="p">():</span>
<span class="k">pass</span>
</code></pre></div></div>
<p>Until I came across this library, I had never used decorator. So I had to first understand that. If you are like me, head over to this wonderful article “<a href="https://realpython.com/primer-on-python-decorators/">Primer on Python Decorators</a>” which explains the concept and use of decorators.</p>
<h2 id="test-drive-rate-limit">Test Drive Rate Limit</h2>
<p>I wanted to take the library for a test drive. So I implemented a simple check. I would write a dummy server that just sent back some fixed string. The client code would make 60 requests but rate limited to 30 requests/minute.</p>
<p>Let’s give this a try.</p>
<h3 id="take-1-wo-rate-limit">Take 1: W/O Rate Limit</h3>
<p>This code has no rate limiting. I wanted to check how long it would take to execute.</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="k">def</span> <span class="nf">access_rate_limited_api</span><span class="p">(</span><span class="n">count</span><span class="p">):</span>
<span class="n">resp</span> <span class="o">=</span> <span class="n">requests</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">'http://192.168.1.2:8000/knockknock'</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">count</span><span class="si">}</span><span class="s">.</span><span class="si">{</span><span class="n">resp</span><span class="p">.</span><span class="n">text</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">60</span><span class="p">):</span>
<span class="n">access_rate_limited_api</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
</code></pre></div></div>
<p>When I execute this code, it just makes a rapid series of calls and all 60 requests are executed within a few seconds.</p>
<h3 id="take-2-with-rate-limit">Take 2: With Rate Limit</h3>
<p>I tweaked the code and added the decorator to restrict the API to 30 calls/minute. I also added an additional decorator to indicate that the any function invocation that can’t succeed will go into sleep and should be retried.</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">from</span> <span class="nn">ratelimit</span> <span class="kn">import</span> <span class="n">limits</span><span class="p">,</span> <span class="n">RateLimitException</span><span class="p">,</span> <span class="n">sleep_and_retry</span>
<span class="n">ONE_MINUTE</span> <span class="o">=</span> <span class="mi">60</span>
<span class="n">MAX_CALLS_PER_MINUTE</span> <span class="o">=</span> <span class="mi">30</span>
<span class="o">@</span><span class="n">sleep_and_retry</span>
<span class="o">@</span><span class="n">limits</span><span class="p">(</span><span class="n">calls</span><span class="o">=</span><span class="n">MAX_CALLS_PER_MINUTE</span><span class="p">,</span> <span class="n">period</span><span class="o">=</span><span class="n">ONE_MINUTE</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">access_rate_limited_api</span><span class="p">(</span><span class="n">count</span><span class="p">):</span>
<span class="n">resp</span> <span class="o">=</span> <span class="n">requests</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">'http://192.168.1.2:8000/knockknock'</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">count</span><span class="si">}</span><span class="s">.</span><span class="si">{</span><span class="n">resp</span><span class="p">.</span><span class="n">text</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">60</span><span class="p">):</span>
<span class="n">access_rate_limited_api</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
</code></pre></div></div>
<p>When I invoke this method, requests numbered 0-29 (30 requests) are executed in one batch and the program halts. After a minute, it starts again and completes the next 30 requests. I can see this sleep in the access log as well. The timestamp jumps from <code class="language-plaintext highlighter-rouge">16:48:06</code> to <code class="language-plaintext highlighter-rouge">16:49:06</code>.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>192.168.1.4 - - [16/Aug/2021:16:48:06 -0700] "GET /knockknock HTTP/1.1" 200 12 "-" "python-requests/2.25.1"
192.168.1.4 - - [16/Aug/2021:16:48:06 -0700] "GET /knockknock HTTP/1.1" 200 12 "-" "python-requests/2.25.1"
...
192.168.1.4 - - [16/Aug/2021:16:49:06 -0700] "GET /knockknock HTTP/1.1" 200 12 "-" "python-requests/2.25.1"
192.168.1.4 - - [16/Aug/2021:16:49:06 -0700] "GET /knockknock HTTP/1.1" 200 12 "-" "python-requests/2.25.1
</code></pre></div></div>
<p>So clearly, rate limiting has occurred.</p>
<h3 id="take-3-rate-limits-with-concurrency">Take 3: Rate Limits with concurrency</h3>
<p>Whenever network access is involved or a complex work-load is being written, we tend to use to multi-threaded approach. If you’d like to learn multi-threading with Python, the article “<a href="https://www.digitalocean.com/community/tutorials/how-to-use-threadpoolexecutor-in-python-3">How To Use ThreadPoolExecutor in Python 3</a>” is a good place to start.</p>
<p>Hence, my next issue was to implement rate limiting in a multi-threaded environment. I wanted to ensure that all the threads behave well and don’t exceed the 30 calls/min limit.</p>
<p>To verify this, I updated the code to add multi-threading. To keep it simple, I started with 3 threads. Using this, I call the same function as before.</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">from</span> <span class="nn">ratelimit</span> <span class="kn">import</span> <span class="n">limits</span><span class="p">,</span> <span class="n">RateLimitException</span><span class="p">,</span> <span class="n">sleep_and_retry</span>
<span class="kn">from</span> <span class="nn">concurrent.futures</span> <span class="kn">import</span> <span class="n">ThreadPoolExecutor</span> <span class="k">as</span> <span class="n">PoolExecutor</span>
<span class="n">ONE_MINUTE</span> <span class="o">=</span> <span class="mi">60</span>
<span class="n">MAX_CALLS_PER_MINUTE</span> <span class="o">=</span> <span class="mi">30</span>
<span class="o">@</span><span class="n">sleep_and_retry</span>
<span class="o">@</span><span class="n">limits</span><span class="p">(</span><span class="n">calls</span><span class="o">=</span><span class="n">MAX_CALLS_PER_MINUTE</span><span class="p">,</span> <span class="n">period</span><span class="o">=</span><span class="n">ONE_MINUTE</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">access_rate_limited_api</span><span class="p">(</span><span class="n">count</span><span class="p">):</span>
<span class="n">resp</span> <span class="o">=</span> <span class="n">requests</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">'http://192.168.1.2:8000/knockknock'</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">count</span><span class="si">}</span><span class="s">.</span><span class="si">{</span><span class="n">resp</span><span class="p">.</span><span class="n">text</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>
<span class="k">with</span> <span class="n">PoolExecutor</span><span class="p">(</span><span class="n">max_workers</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span> <span class="k">as</span> <span class="n">executor</span><span class="p">:</span>
<span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="n">executor</span><span class="p">.</span><span class="nb">map</span><span class="p">(</span><span class="n">access_rate_limited_api</span><span class="p">,</span> <span class="nb">range</span><span class="p">(</span><span class="mi">60</span><span class="p">)):</span>
<span class="k">pass</span>
</code></pre></div></div>
<p>As before, in the access log, there were 30 requests within the same minute, a gap of 1 minute followed by the remaining 30 requests.</p>
<h2 id="putting-it-together">Putting it together</h2>
<p>The example I have is a very simple use case. In my case, the final use-case was to ensure that I was within the rate limit for <a href="https://cloudinary.com/documentation/admin_api">Cloudinary’s Admin API</a>. In my case, the rate limit I was desiring was 3000 requests per hour. This translates to 50 requests minute. I was trying to extract information about a set of resources and print to a CSV file. By using the requests library with a concurrency of 5, I was able to achieve the desired throughput while remaining within the rate limits imposed by the API.</p>rakshay