<?xml version="1.0" encoding="UTF-8"?>
<rss  xmlns:atom="http://www.w3.org/2005/Atom" 
      xmlns:media="http://search.yahoo.com/mrss/" 
      xmlns:content="http://purl.org/rss/1.0/modules/content/" 
      xmlns:dc="http://purl.org/dc/elements/1.1/" 
      version="2.0">
<channel>
<title>عبد الكريم الخطيب - Abdelkareem Elkhateb | AI Researcher &amp; Arabic NLP Specialist</title>
<link>https://kareemai.com/til/</link>
<atom:link href="https://kareemai.com/til/index.xml" rel="self" type="application/rss+xml"/>
<description>Latest TILs by Kareem</description>
<image>
<url>https://kareemai.com/kareem.jpg</url>
<title>عبد الكريم الخطيب - Abdelkareem Elkhateb | AI Researcher &amp; Arabic NLP Specialist</title>
<link>https://kareemai.com/til/</link>
</image>
<generator>quarto-1.8.27</generator>
<lastBuildDate>Sun, 14 Dec 2025 22:00:00 GMT</lastBuildDate>
<item>
  <title>AI Research Challenges: The GPU Barrier for Researchers</title>
  <dc:creator>kareem </dc:creator>
  <link>https://kareemai.com/til/tils/2025-12-15.html</link>
  <description><![CDATA[ 





<p>Imagine a blind trying to walk in a new city he didn’t visit before and he didn’t had a stick in this hand he just had an idiot rat who guides him with a rope, this rat sometime tell the man : Hey, Kareem can you wait some time I will go in batches to find the bus station. 72 hours later you get hungry , lost your mind and your poor can’t get an Uber! Then the rat come to you and said I didn’t find a bus station, let’s go and find a restaurant 72 hours later the rat is out of control and get panic from the long routes in this new city. You are hungry and the rat can’t help he can just guide to a little places and in these little places you need to wait multiple hours to get a response from rat.</p>
<p>This is my life being a GPU poor, I want to fine-tune an embedding model which is something trivial in the AI compute I will need to get GPU and based on the dataset size to fine-tune in my college it’s a titan rtx it takes 72 so all my ideas and research will wait until the 72 finishes!</p>
<p>The lack of immediate feedback is the bottleneck for ai if I was an engineer a frontend developer every change I made I see an immediate feedback on the screen, the flow continue until I had a good prototype in less than 2 hours and I can change ..etc this is what makes AI sicks! Any idea about anything to validate it you will spend months if you are GPU poor and doing ai research on kaggle or colap free instances is not good experience if you will use the free you are limited but the VRAM, time until they suspend the instance…etc this is not how AI programming should be. <strong>I hope I can get an rtx 5090 in the next months</strong></p>
<hr>
<section id="more-from-my-site" class="level3">
<h3 class="anchored" data-anchor-id="more-from-my-site">More from my site</h3>
<p>If you enjoyed this reflection on the state of AI research hardware, you might also be interested in my <a href="../../papers.html">Research Papers</a> where I share the results of my work, or my <a href="../../blog/feed.html">Main Blog</a> for deeper technical dives. You can also return to my <a href="../../index.html">Homepage</a>.</p>


</section>

 ]]></description>
  <category>blogging</category>
  <category>til</category>
  <category>blog/opinion/tech</category>
  <guid>https://kareemai.com/til/tils/2025-12-15.html</guid>
  <pubDate>Sun, 14 Dec 2025 22:00:00 GMT</pubDate>
  <media:content url="https://kareemai.com/til/tils/til.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>Rust for Machine Learning: Building AI Tools and Data Pipelines in 2026</title>
  <dc:creator>kareem </dc:creator>
  <link>https://kareemai.com/til/tils/2025-12-14.html</link>
  <description><![CDATA[ 





<section id="why-rust-for-machine-learning" class="level2">
<h2 class="anchored" data-anchor-id="why-rust-for-machine-learning">Why Rust for Machine Learning?</h2>
<p>Yesterday, I started thinking about building a keyword spell checker for Arabic and contributing to المعلم القرانئ project. This led me down a rabbit hole: most modern ML infrastructure is built in Rust for a reason—performance, memory safety, and zero-cost abstractions matter when you’re dealing with embeddings and vector databases at scale.</p>
<p>These tools I use daily are built in Rust:</p>
<p><strong>Polars</strong> — Lightning-fast dataframe processing. I use it for all data preprocessing pipelines. It’s not just fast; the API forces you to think about your operations differently than pandas.</p>
<p><strong>Qdrant</strong> — My primary vector database. The fact that it’s written in Rust means I can deploy it efficiently and trust the memory model for high-throughput search.</p>
<p><strong>Candle + Fast-Falid</strong> — Rust inference engines and late interaction indexing. Understanding how these work at the systems level reveals why Rust is the right choice for production ML infrastructure.</p>
<p>There’s a pattern here: Rust isn’t just “a better language.” It forces architects to make choices visible—memory layout, concurrency models, error handling. This is exactly what ML engineers need to understand.</p>
</section>
<section id="learning-from-first-principles-أحمد-فرغلs-رست-للغلابة-series" class="level2">
<h2 class="anchored" data-anchor-id="learning-from-first-principles-أحمد-فرغلs-رست-للغلابة-series">Learning from First Principles: أحمد فرغل’s رست للغلابة Series</h2>
<p>I found Ahmed Farghly’s Arabic Rust course, and it’s been transformative. Each video is ~3 hours of deep systems thinking. I’ve attempted Rust twice before—read the official book years ago—but something didn’t click until now.</p>
<p>What makes this series special: it’s not teaching “Rust syntax.” It’s teaching <strong>systems thinking through Rust</strong>. Ahmed explains how Operating System concepts—memory layout, alignment, allocators—become visible in Rust code.</p>
<p>Example from video 1: When you define a struct like this:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode rust code-with-copy"><code class="sourceCode rust"><span id="cb1-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-2">    a<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">u8</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb1-3">    b<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">i32</span></span>
<span id="cb1-4"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>He doesn’t just say “it compiles.” He shows you:</p>
<ul>
<li><strong>Why</strong> the order doesn’t matter to Rust (alignment rules)</li>
<li><strong>How</strong> the compiler pads the struct in memory</li>
<li><strong>Why</strong> this is different from C (where order matters)</li>
<li><strong>What</strong> system calls happen under the hood</li>
<li><strong>How</strong> this connects to heap vs stack allocation</li>
<li><strong>Why</strong> Rust has macros at all (they’re solving real compiler problems)</li>
</ul>
<p>Concepts that seemed abstract before—lifetimes, borrowing, ownership—suddenly make sense because you understand the memory model underneath. That’s the key: Rust semantics emerge from lower-level realities, not arbitrary restrictions.</p>
<p>This series is rare—especially for Arabic speakers. ⭐⭐⭐</p>
<section id="ml-projects-in-rust-from-learning-to-building" class="level3">
<h3 class="anchored" data-anchor-id="ml-projects-in-rust-from-learning-to-building">ML Projects in Rust: From Learning to Building</h3>
<p>Once I’ve built a foundation, here’s what I’m planning to build:</p>
<p><strong>1. Documentation + Semantic Search</strong> — Rust documentation is leagues ahead of Python’s. I want to build a tool that embeds Rust docs with static embeddings and makes code-aware search actually useful.</p>
<p><strong>2. Lialia</strong> — Arabic keyword spell checker with lexical search. This bridges my native language and ML research.</p>
<p><strong>3. Semantic Search Stack</strong> — The big ones:</p>
<ul>
<li><strong>Pyversity in Rust</strong> — Rebuilding my Python semantic search library in Rust for production deployment</li>
<li><strong>Semhash + Qdrant</strong> — Semantic hashing combined with vector search is showing up in my GSC data; I want to understand the implementation depth</li>
<li><strong>BM25 Rust</strong> — Hybrid retrieval combining lexical (BM25) and semantic search</li>
</ul>
<p><strong>4. DSPY-powered Tools</strong> — RSS reader that uses DSPY for reasoning over feeds</p>
<p><strong>5. Mgrep</strong> — Semantic grep for Rust codebases</p>
<p>The pattern: each project forces me to understand both the ML theory <em>and</em> how systems software actually works. That’s the point.</p>
</section>
</section>
<section id="references" class="level2">
<h2 class="anchored" data-anchor-id="references">References</h2>
<ol type="1">
<li><a href="https://youtube.com/playlist?list=PLald6EODoOJU0GMuYHlkS9MLhTPE7HiaT&amp;si=3O-9VHNwmSN5M13t">رست للغلابة</a></li>
</ol>
<hr>
<section id="internal-resources" class="level3">
<h3 class="anchored" data-anchor-id="internal-resources">Internal Resources</h3>
<p>If you’re interested in more about Rust, AI engineering, and my research, explore these sections:</p>
<ul>
<li><a href="../../papers.html">My Research Papers</a></li>
<li><a href="../../oss/opensource.html">Open Source Contributions</a></li>
<li><a href="../../til/index.html">Today I Learned Index</a></li>
<li><a href="../../blog/feed.html">Main Blog Index</a></li>
</ul>


</section>
</section>

 ]]></description>
  <category>blogging</category>
  <category>til</category>
  <category>blog/status/complete</category>
  <category>blog/status/published</category>
  <category>rust</category>
  <guid>https://kareemai.com/til/tils/2025-12-14.html</guid>
  <pubDate>Sat, 13 Dec 2025 22:00:00 GMT</pubDate>
  <media:content url="https://kareemai.com/til/tils/til.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>Arabic NLP Fundamentals: From Sparse Embeddings and BM25 to Dynamic Programming</title>
  <dc:creator>kareem </dc:creator>
  <link>https://kareemai.com/til/tils/2025-12-13.html</link>
  <description><![CDATA[ 





<section id="fixing-the-gap-classical-nlp-fundamentals" class="level2">
<h2 class="anchored" data-anchor-id="fixing-the-gap-classical-nlp-fundamentals">Fixing the Gap: Classical NLP Fundamentals</h2>
<p>For years, I’ve skimmed over foundational NLP concepts:</p>
<ul>
<li>TF-IDF and BM25 (lexical retrieval)</li>
<li>Sparse embeddings (n-gram subsampling + MLP compression)</li>
<li>Dynamic programming algorithms (edit distance, Viterbi)</li>
</ul>
<p>I understood the new stuff—BERT, transformers, semantic embeddings—but the classical foundations felt disconnected. The gap became obvious: I never built these algorithms myself. I never saw <em>why</em> sparse embeddings exist (they’re solving speed + interpretability problems dense methods don’t) or <em>how</em> to optimize them.</p>
<p>I decided to rebuild from first principles using:</p>
<ol type="1">
<li><strong>Jurafsky &amp; Martin’s “Speech and Language Processing”</strong> (3rd edition draft)</li>
<li><strong>Implementing algorithms in Arabic code</strong></li>
<li><strong>Problem-solving practice through LeetCode</strong></li>
</ol>
<section id="learning-roadmap" class="level3">
<h3 class="anchored" data-anchor-id="learning-roadmap">Learning Roadmap</h3>
<p><strong>Phase 1: Lexical Methods</strong></p>
<ul>
<li>Word2vec and n-gram theory</li>
<li>Stemming and tokenization for Arabic</li>
<li>TF-IDF and BM25 ranking</li>
<li>BMX (dense-sparse hybrid from Mixedbread)</li>
</ul>
<p><strong>Phase 2: Sparse Embeddings</strong></p>
<ul>
<li>SPLADE and learned sparse vectors</li>
<li>Training sparse embeddings with SBERT</li>
<li>Optimization and interpretability</li>
</ul>
<p><strong>Phase 3: Dynamic Programming &amp; Alignment</strong> (current)</p>
<ul>
<li>Minimum edit distance (Levenshtein)</li>
<li>Word alignment algorithms</li>
<li>Viterbi and HMMs</li>
</ul>
<p>Each builds on the last. You can’t understand why sparse embeddings matter without understanding BM25. You can’t implement them efficiently without mastering dynamic programming.</p>
</section>
</section>
<section id="first-chapter-tokenization-unicode-minimum-edit-distance" class="level2">
<h2 class="anchored" data-anchor-id="first-chapter-tokenization-unicode-minimum-edit-distance">First Chapter: Tokenization, Unicode &amp; Minimum Edit Distance</h2>
<p>Chapter 1 of Jurafsky covers:</p>
<ul>
<li><strong>Words and tokens</strong>: What counts as a “word” when you’re dealing with Arabic morphology?</li>
<li><strong>Unicode and encoding</strong>: How different languages store characters differently (critical for Arabic preprocessing)</li>
<li><strong>Regular expressions</strong>: Practical NLP pattern matching</li>
<li><strong>Minimum edit distance</strong>: The algorithm that powers spell-checking and text similarity</li>
</ul>
<p>The minimum edit distance is brilliant but requires implementation from scratch. You need to think about:</p>
<ul>
<li>State representation (the matrix)</li>
<li>Recurrence relations (how cells depend on neighbors)</li>
<li>Backtracking (to recover the actual edits)</li>
</ul>
<p>I couldn’t implement it cleanly at first. That’s when I realized: <strong>my problem-solving muscles are rusty.</strong></p>
<section id="deliberate-practice-neetcode-ml-problems" class="level3">
<h3 class="anchored" data-anchor-id="deliberate-practice-neetcode-ml-problems">Deliberate Practice: NeetCode + ML Problems</h3>
<p>I found <a href="https://neetcode.io">NeetCode</a>—cleaner and more focused than LeetCode. In the last week:</p>
<ul>
<li>Solved 11 problems (3 easy, 8 medium+)</li>
<li>Built Python fluency around <code>collections.Counter</code>, hashmaps, list comprehensions</li>
<li>Code works but isn’t always optimal—that’s fine; repetition matters more than perfection at this stage</li>
<li>The real win: restored my patience for thinking through problems step-by-step</li>
</ul>
<p>The plan:</p>
<ul>
<li><strong>Month 1</strong>: Finish 150 NeetCode problems, focus on dynamic programming (edit distance, Viterbi, longest common subsequence)</li>
<li><strong>Month 2</strong>: Transition to <a href="https://deep-ml.com">Deep-ML</a>—same structure but for ML algorithms instead of data structures</li>
<li><strong>Parallel</strong>: Implement each NLP chapter concept in Arabic-ready code</li>
</ul>
</section>
</section>
<section id="building-smart-arabic-keyword-checker" class="level2">
<h2 class="anchored" data-anchor-id="building-smart-arabic-keyword-checker">Building: Smart Arabic Keyword Checker</h2>
<p>The alignment chapter inspired a concrete project: <strong>build a spell checker for Arabic that understands context and domain.</strong></p>
<p>Current keyboards (suggest random near-misses). A smarter version would:</p>
<ol type="1">
<li><strong>Technical terminology mapping</strong>
<ul>
<li>Suggest Arabic equivalents for ML terms</li>
<li>Example: “embedding model” → “نماذج التضمين”</li>
<li>Example: “vector database” → “قاعدة بيانات المتجهات”</li>
</ul></li>
<li><strong>Persona-aware suggestions</strong>
<ul>
<li>Different recommendations for engineers, doctors, writers</li>
<li>Your vocabulary profile informs what “correct” means</li>
</ul></li>
<li><strong>Federated learning</strong> (like Gboard)
<ul>
<li>Learn from your typing without uploading data</li>
</ul></li>
<li><strong>Arabic grammar correction</strong>
<ul>
<li>Not just spelling; handle diacritics, agreement, tense</li>
</ul></li>
<li><strong>Adaptive learning</strong>
<ul>
<li>Improve suggestions based on what you accept/reject</li>
</ul></li>
</ol>
<p>The tech stack: dynamic programming for edit distance, sparse embeddings for semantic similarity, possibly Rust for performance.</p>
<section id="references" class="level3">
<h3 class="anchored" data-anchor-id="references">References</h3>
<ol type="1">
<li><a href="https://web.stanford.edu/~jurafsky/slp3/">The NLP book</a></li>
</ol>
<hr>
</section>
<section id="internal-resources" class="level3">
<h3 class="anchored" data-anchor-id="internal-resources">Internal Resources</h3>
<p>If you are interested in more structured deep dives, check out my <a href="../../blog/feed.html">Blog</a> or my <a href="../../papers.html">Research Papers</a>. For my work on tools and libraries, visit the <a href="../../oss/opensource.html">Open Source</a> section. You can also explore more daily notes in the <a href="../../til/index.html">TIL Index</a>.</p>


</section>
</section>

 ]]></description>
  <category>blogging</category>
  <category>til</category>
  <category>blog/status/published</category>
  <category>blog/status/complete</category>
  <category>blog/learn/journey</category>
  <guid>https://kareemai.com/til/tils/2025-12-13.html</guid>
  <pubDate>Fri, 12 Dec 2025 22:00:00 GMT</pubDate>
  <media:content url="https://kareemai.com/til/tils/til.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>Arabic Tokenizer Comparison: AraModernBert vs AraBERT v2 (With Metrics)</title>
  <dc:creator>kareem </dc:creator>
  <link>https://kareemai.com/til/tils/2025-10-21.html</link>
  <description><![CDATA[ 





<section id="introduction" class="level2">
<h2 class="anchored" data-anchor-id="introduction">Introduction</h2>
<p>When working with Arabic language models, choosing the right tokenizer can significantly impact model performance and efficiency. In this post, I’ll share my experience comparing two popular Arabic tokenizers: <strong>AraModernBert</strong> (using SentencePiece) and <strong>AraBERT v2</strong>.</p>
<p>The short answer: <strong>AraModernBert is substantially more efficient, handling 15-71% fewer tokens for the same Arabic text.</strong> Here’s why and when that matters.</p>
</section>
<section id="why-tokenizer-evaluation-matters" class="level2">
<h2 class="anchored" data-anchor-id="why-tokenizer-evaluation-matters">Why Tokenizer Evaluation Matters</h2>
<p>After reading the comprehensive guide on <a href="https://www.fast.ai/posts/2025-10-16-karpathy-tokenizers.html#token-efficiency">GPT tokenizers</a>, I realized that tokenization is often overlooked but critically important. Poor tokenization can lead to:</p>
<ul>
<li>Inefficient use of limited context windows</li>
<li>Higher computational costs (you pay per token!)</li>
<li>Worse model performance, especially for non-English languages</li>
</ul>
<p>For Arabic specifically, tokenization is challenging because:</p>
<ul>
<li>Arabic has rich morphology with prefixes and suffixes</li>
<li>Different dialects (Egyptian, Levantine, Gulf) have varying vocabulary</li>
<li>Diacritical marks (tashkeel) add complexity</li>
<li>Tasks that need tashkeel (diacritical marks): speech synthesis, grammar correction, poetry analysis</li>
</ul>
</section>
<section id="the-evaluation-framework" class="level2">
<h2 class="anchored" data-anchor-id="the-evaluation-framework">The Evaluation Framework</h2>
<p>I built a simple evaluation function to measure tokenizer quality:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb1-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> evaluate_tokenizer(text, tokenizer):</span>
<span id="cb1-2">    number_of_tokens <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(tokenizer.tokenize(text))</span>
<span id="cb1-3">    number_of_bytes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(text.encode(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'utf-8'</span>))</span>
<span id="cb1-4">    number_of_words <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(text.split(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">" "</span>))</span>
<span id="cb1-5">    fertility <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> number_of_tokens <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> number_of_words </span>
<span id="cb1-6">    compression_ratio <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> number_of_bytes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> number_of_tokens </span>
<span id="cb1-7">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> {</span>
<span id="cb1-8">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"fertility"</span>: fertility,</span>
<span id="cb1-9">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"compression_ratio"</span>: compression_ratio,</span>
<span id="cb1-10">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"total_tokens"</span>: number_of_tokens</span>
<span id="cb1-11">    }</span></code></pre></div></div>
<section id="key-metrics" class="level3">
<h3 class="anchored" data-anchor-id="key-metrics">Key Metrics</h3>
<ol type="1">
<li><strong>Fertility Rate</strong> (tokens/word): Lower is better. Measures how many tokens are needed per word.</li>
<li><strong>Compression Ratio</strong> (bytes/token): Higher is better. Measures how efficiently the tokenizer compresses text.</li>
<li><strong>Total Tokens</strong>: The raw count for the given text.</li>
</ol>
</section>
</section>
<section id="the-contenders" class="level2">
<h2 class="anchored" data-anchor-id="the-contenders">The Contenders</h2>
<section id="aramodernbert" class="level3">
<h3 class="anchored" data-anchor-id="aramodernbert">AraModernBert</h3>
<ul>
<li><strong>Vocabulary</strong>: 50,280 tokens</li>
<li><strong>Training Data</strong>: 100GB of Arabic text</li>
<li><strong>Architecture</strong>: ModernBERT with transtokenization</li>
<li><strong>Context Window</strong>: 8,192 tokens</li>
</ul>
</section>
<section id="arabert-v2" class="level3">
<h3 class="anchored" data-anchor-id="arabert-v2">AraBERT v2</h3>
<ul>
<li><strong>Vocabulary</strong>: ~30,000 tokens</li>
<li><strong>Training Data</strong>: 77GB of Arabic text</li>
<li><strong>Architecture</strong>: BERT-base</li>
<li><strong>Pre-segmentation</strong>: Uses Farasa segmenter</li>
</ul>
</section>
</section>
<section id="test-results" class="level2">
<h2 class="anchored" data-anchor-id="test-results">Test Results</h2>
<p>I tested both tokenizers on three different Arabic texts with Encoder only for now more to come later!:</p>
<section id="test-1-modern-standard-arabic" class="level3">
<h3 class="anchored" data-anchor-id="test-1-modern-standard-arabic">Test 1: Modern Standard Arabic</h3>
<p><strong>Text</strong>: “مرحبا كيف حالك اليوم”</p>
<table class="caption-top table">
<thead>
<tr class="header">
<th>Tokenizer</th>
<th>Fertility</th>
<th>Compression Ratio</th>
<th>Total Tokens</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>AraModernBert</td>
<td>1.25</td>
<td>7.4</td>
<td>5</td>
</tr>
<tr class="even">
<td>AraBERT v2</td>
<td>1.5</td>
<td>6.17</td>
<td>6</td>
</tr>
</tbody>
</table>
</section>
<section id="test-2-egyptian-dialect" class="level3">
<h3 class="anchored" data-anchor-id="test-2-egyptian-dialect">Test 2: Egyptian Dialect</h3>
<p><strong>Text</strong>: “إزيك يا صاحبي عامل إيه”</p>
<table class="caption-top table">
<thead>
<tr class="header">
<th>Tokenizer</th>
<th>Fertility</th>
<th>Compression Ratio</th>
<th>Total Tokens</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>AraModernBert</td>
<td>1.2</td>
<td>6.67</td>
<td>6</td>
</tr>
<tr class="even">
<td>AraBERT v2</td>
<td>1.4</td>
<td>5.71</td>
<td>7</td>
</tr>
</tbody>
</table>
</section>
<section id="test-3-technicalformal-text" class="level3">
<h3 class="anchored" data-anchor-id="test-3-technicalformal-text">Test 3: Technical/Formal Text</h3>
<p><strong>Text</strong>: “الذكاء الاصطناعي يغير العالم بسرعة كبيرة”</p>
<table class="caption-top table">
<thead>
<tr class="header">
<th>Tokenizer</th>
<th>Fertility</th>
<th>Compression Ratio</th>
<th>Total Tokens</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>AraModernBert</td>
<td>1.17</td>
<td>10.71</td>
<td>7</td>
</tr>
<tr class="even">
<td>AraBERT v2</td>
<td>2.0</td>
<td>6.25</td>
<td><strong>12</strong></td>
</tr>
</tbody>
</table>
</section>
</section>
<section id="key-findings" class="level2">
<h2 class="anchored" data-anchor-id="key-findings">Key Findings</h2>
<section id="aramodernbert-is-consistently-more-efficient" class="level3">
<h3 class="anchored" data-anchor-id="aramodernbert-is-consistently-more-efficient">1. AraModernBert is Consistently More Efficient</h3>
<p>Across all three tests, AraModernBert showed:</p>
<ul>
<li><p><strong>Lower fertility</strong> (15-42% fewer tokens per word)</p></li>
<li><p><strong>Higher compression ratio</strong> (14-71% better compression)</p></li>
<li><p><strong>Fewer total tokens</strong> needed for the same text</p></li>
</ul>
</section>
<section id="the-gap-widens-with-complex-text" class="level3">
<h3 class="anchored" data-anchor-id="the-gap-widens-with-complex-text">2. The Gap Widens with Complex Text</h3>
<p>The most dramatic difference appeared in Test 3 (technical text):</p>
<ul>
<li><p>AraModernBert: 7 tokens</p></li>
<li><p>AraBERT v2: 12 tokens (<strong>71% more!</strong>)</p></li>
</ul>
<p>This means for an 8K context window, AraModernBert can fit significantly more Arabic text.</p>
</section>
<section id="both-handle-dialects-reasonably-well" class="level3">
<h3 class="anchored" data-anchor-id="both-handle-dialects-reasonably-well">3. Both Handle Dialects Reasonably Well</h3>
<p>The Egyptian dialect test (Test 2) showed both tokenizers maintained similar efficiency to MSA, though AraModernBert still outperformed.</p>
</section>
</section>
<section id="why-aramodernbert-performs-better" class="level2">
<h2 class="anchored" data-anchor-id="why-aramodernbert-performs-better">Why AraModernBert Performs Better</h2>
<section id="larger-vocabulary-50k-vs-30k-tokens" class="level3">
<h3 class="anchored" data-anchor-id="larger-vocabulary-50k-vs-30k-tokens">Larger Vocabulary (50K vs 30K tokens)</h3>
<p>More tokens means the model can learn longer, more common Arabic word chunks as single tokens.</p>
<p>This is especially important for Arabic’s morphologically rich structure.</p>
</section>
<section id="more-training-data-100gb-vs-77gb" class="level3">
<h3 class="anchored" data-anchor-id="more-training-data-100gb-vs-77gb">More Training Data (100GB vs 77GB)</h3>
<p>More data leads to better byte-pair encoding merges that reflect actual Arabic usage patterns.</p>
</section>
<section id="modern-architecture" class="level3">
<h3 class="anchored" data-anchor-id="modern-architecture">Modern Architecture</h3>
<p>AraModernBert uses transtokenization - a technique that optimally initializes embeddings when creating the tokenizer, leading to better learned representations.</p>
</section>
<section id="recency-advantage" class="level3">
<h3 class="anchored" data-anchor-id="recency-advantage">Recency Advantage</h3>
<p>Trained in 2024 vs 2020, AraModernBert benefits from more recent data and improved training techniques.</p>
</section>
</section>
<section id="practical-implications" class="level2">
<h2 class="anchored" data-anchor-id="practical-implications">Practical Implications</h2>
<section id="for-model-training" class="level3">
<h3 class="anchored" data-anchor-id="for-model-training">For Model Training</h3>
<ul>
<li><strong>Context efficiency</strong>: AraModernBert lets you fit ~40% more Arabic text in the same context window</li>
<li><strong>Cost savings</strong>: Fewer tokens = lower training costs</li>
<li><strong>Better performance</strong>: More efficient tokenization often correlates with better downstream task performance</li>
</ul>
</section>
<section id="for-production-systems" class="level3">
<h3 class="anchored" data-anchor-id="for-production-systems">For Production Systems</h3>
<ul>
<li><strong>API costs</strong>: Pay per token, so more efficient tokenization = lower costs</li>
<li><strong>Latency</strong>: Fewer tokens to process = faster inference</li>
<li><strong>Memory</strong>: Smaller token sequences = lower memory footprint</li>
</ul>
</section>
</section>
<section id="should-you-train-your-own-tokenizer" class="level2">
<h2 class="anchored" data-anchor-id="should-you-train-your-own-tokenizer">Should You Train Your Own Tokenizer?</h2>
<p>After this evaluation, here’s my thinking:</p>
<p><strong>Use AraModernBert if:</strong></p>
<ul>
<li>You’re working with Modern Standard Arabic or mixed dialects</li>
<li>You want state-of-the-art efficiency out of the box</li>
<li>You don’t have massive compute resources for training</li>
</ul>
<p><strong>Train your own if:</strong></p>
<ul>
<li>You have a very specific domain (medical, legal, etc.)</li>
<li>You’re working with a specific dialect extensively (pure Egyptian, Levantine, etc.)</li>
<li>You have unique requirements (handling tashkeel differently, etc.)</li>
</ul>
<p>For my Egyptian Arabic use case, I’m leaning toward using AraModernBert’s tokenizer as-is, since:</p>
<ol type="1">
<li>It already handles Egyptian dialect reasonably well</li>
<li>The 50K vocabulary is large enough to be flexible</li>
<li>Training a custom tokenizer requires significant effort and data</li>
</ol>
</section>
<section id="next-steps" class="level2">
<h2 class="anchored" data-anchor-id="next-steps">Next Steps</h2>
<ol type="1">
<li><strong>Test on real data</strong>: Evaluate on actual Egyptian Arabic corpus (FineWeb Egyptian)</li>
<li><strong>Compare with SentencePiece</strong>: Test a SentencePiece tokenizer trained on Arabic</li>
<li><strong>Measure downstream performance</strong>: Tokenizer efficiency doesn’t always equal better model performance</li>
<li><strong>Investigate tashkeel handling</strong>: How do these tokenizers handle diacritical marks?</li>
</ol>
</section>
<section id="conclusion" class="level2">
<h2 class="anchored" data-anchor-id="conclusion">Conclusion</h2>
<p>Tokenizer evaluation revealed that <strong>AraModernBert significantly outperforms AraBERT v2</strong> in efficiency metrics, with 15-71% fewer tokens needed for the same Arabic text.</p>
<p>This translates to real cost savings and performance improvements in production systems.</p>
<p>The key lesson: <strong>don’t assume all tokenizers are equal</strong>. A few hours of evaluation can save months of headaches and significant costs down the line.</p>
<section id="internal-resources" class="level3">
<h3 class="anchored" data-anchor-id="internal-resources">Internal Resources</h3>
<p>For more insights into Arabic NLP and AI engineering, visit my <a href="../../papers.html">Research Papers</a> or explore my <a href="../../oss/opensource.html">Open Source Projects</a>. You can also find more daily discoveries in the <a href="../../til/index.html">TIL Index</a>.</p>
</section>
</section>
<section id="code-repository" class="level2">
<h2 class="anchored" data-anchor-id="code-repository">Code Repository</h2>
<p>The complete evaluation code is available as a simple function:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb2-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> evaluate_tokenizer(text, tokenizer):</span>
<span id="cb2-2">    number_of_tokens <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(tokenizer.tokenize(text))</span>
<span id="cb2-3">    number_of_bytes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(text.encode(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'utf-8'</span>))</span>
<span id="cb2-4">    number_of_words <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(text.split(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">" "</span>))</span>
<span id="cb2-5">    fertility <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> number_of_tokens <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> number_of_words </span>
<span id="cb2-6">    compression_ratio <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> number_of_bytes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> number_of_tokens </span>
<span id="cb2-7">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> {</span>
<span id="cb2-8">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"fertility"</span>: fertility,</span>
<span id="cb2-9">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"compression_ratio"</span>: compression_ratio,</span>
<span id="cb2-10">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"total_tokens"</span>: number_of_tokens</span>
<span id="cb2-11">    }</span></code></pre></div></div>
<p>this post was built with guide from Amazing <a href="https://solve.it.com/?via_id=t1hpiqbn">Solveit</a></p>


</section>

 ]]></description>
  <category>blogging</category>
  <category>til</category>
  <category>nlp</category>
  <category>ai</category>
  <category>blog/learn/concept</category>
  <category>blog/benchmark</category>
  <category>blog/status/complete</category>
  <guid>https://kareemai.com/til/tils/2025-10-21.html</guid>
  <pubDate>Mon, 20 Oct 2025 21:00:00 GMT</pubDate>
  <media:content url="https://kareemai.com/til/tils/til.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>AI Engineering Careers: Connecting with Minds in Machine Learning</title>
  <dc:creator>kareem </dc:creator>
  <link>https://kareemai.com/til/tils/2025-06-06-til.html</link>
  <description><![CDATA[ 





<p>Here is the corrected version with grammar errors fixed and improved clarity, while preserving the original meaning and tone:</p>
<ul>
<li>Get paid for your knowledge!</li>
<li>I’m not interested in all this talk about being replaced by AI. If AI can replace an engineer’s mind, it will replace everything in the world.</li>
<li>When this happens, it won’t really matter!</li>
<li>I got my first job one year after graduation with a good salary for my experience and the local currency.</li>
<li>الحمد والشكر والفضل لله وحده.</li>
<li>Actually, I got two jobs, not one!</li>
<li>I landed a full-time AI Engineer position at a startup that is already operational with its own customers, plus a part-time role with flexible meetings. I’m the wildcard—maybe even the AI—in this startup, which is set to receive funding in the coming weeks.</li>
<li>This might give the impression that I’m a great engineer, but I’m not!</li>
<li>I’m not good at programming; I’m below average and can barely do cool stuff on my own. I only know some solutions to try, and I’m familiar with multiple resources and places to get help. I love asking more experienced people for feedback.</li>
<li>I can only say that I love this field a lot! It’s very interesting. With just a laptop and my mind, I can create things the world needs and will pay for!</li>
<li>This may sound silly, but it’s an amazing idea to think about, especially for someone like me who doesn’t enjoy the outside world or dealing with people in real life.</li>
<li>What I like is that the world is connected, and you can gain recognition quickly if you’re doing real work and building connections with people in your field.</li>
<li>I’m interested in Machine Learning and focus on niche areas where not many people are working. In my language, there’s little competition, which gives me a unique edge! But in reality, I’m below average; the basics I explore in these areas are enough for now.</li>
<li>I don’t advise anyone to do this, but I want to say that when you try your best, reflect on your goals, start crafting your ideas, and engage with others’ ideas, your influence and impact will grow significantly.</li>
<li>I’ve met many ordinary people who simply read documentation, ask questions about what they don’t know, and are beginners, yet others look at them and think, “Wow, they must be geniuses!”</li>
<li>But they’re not! You may have more knowledge and experience than them, but business, your birthplace, and the college you graduated from are strong factors in determining your path.</li>
<li>You can reach great places without these, but they accelerate your progress!</li>
<li>We all know the story of the child who learned programming at 11 years old and now, at 25, codes as easily as walking.</li>
<li>What I’ve found is that you can still build great connections with someone who has 10 years more experience than you, and they might even say, “You’re a smart person! I want you to work with me.”</li>
<li>We’re all limited, and there will always be gaps that require other minds to fill. The great thing is that we grow faster when we connect with such minds!</li>
<li>I really admire the work from the AnswerDotAI team. I find that Jeremy Howard has a profound impact on how I think about AI and learning.</li>
<li>The courses I’ve taken with him, the community, and the tools make me feel ahead of the curve and capable of creating things!</li>
<li>When you start following people like Omar Khatab, Benjamin, Antoine, Tom Arson, and many others, and interact with their work, you begin to gain weight in these spaces. I’m not just talking about getting a job—I’m talking about the level of ideas.</li>
<li>There are people watching, people building tools around concepts, and people creating new concepts!</li>
<li>I wish I could reach the cutting edge of knowledge. This may not be precise, but I see it as a journey I want to pursue.</li>
<li>There’s more to say, but this world has immense potential for smart people—not in terms of marketing or being a shallow influencer.</li>
<li>I want to say that I have many ideas I want to create and share with other minds. I believe I’ll be able to make a positive impact in the areas I’m passionate about and improve Islamic tech and Arabic NLP.</li>
</ul>
<hr>
<section id="internal-resources" class="level3">
<h3 class="anchored" data-anchor-id="internal-resources">Internal Resources</h3>
<p>If you found these career reflections and thoughts on the AI field useful, you might also be interested in:</p>
<ul>
<li><a href="../../papers.html">My Research Papers</a></li>
<li><a href="../../oss/opensource.html">Open Source Contributions</a></li>
<li><a href="../../blog/feed.html">Main Blog Index</a></li>
<li><a href="../../til/index.html">Today I Learned Index</a></li>
</ul>


</section>

 ]]></description>
  <category>blogging</category>
  <category>til</category>
  <guid>https://kareemai.com/til/tils/2025-06-06-til.html</guid>
  <pubDate>Thu, 05 Jun 2025 21:00:00 GMT</pubDate>
  <media:content url="https://kareemai.com/til/tils/til.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>PyLate Tutorial: Vector Indexing and Retrieval with ColBERT (Complete Guide)</title>
  <dc:creator>kareem </dc:creator>
  <link>https://kareemai.com/til/tils/2025-05-28-til.html</link>
  <description><![CDATA[ 





<section id="pylate-tutorial-vector-indexing-and-retrieval-with-colbert" class="level1">
<h1>PyLate Tutorial: Vector Indexing and Retrieval with ColBERT</h1>
<p><strong>PyLate</strong> is a Python library that simplifies dense vector retrieval with ColBERT (Contextualized Late Interaction over BERT). It handles indexing, querying, and evaluation of dense retrieval systems. This guide covers everything you need to work with PyLate in production: data formats, indexing strategies, and evaluation pipelines.</p>
<section id="what-youll-learn" class="level2">
<h2 class="anchored" data-anchor-id="what-youll-learn">What You’ll Learn</h2>
<ul>
<li>How PyLate and ColBERT work together for dense retrieval</li>
<li>Three dataset formats (Triplet, Structured, Passage Ranking)</li>
<li>Data conversion strategies for large datasets</li>
<li>PLAID indexing and document processing</li>
<li>IR metrics (NDCG, MAP, Recall) and evaluation</li>
<li>Common pitfalls and performance optimization</li>
</ul>
</section>
<section id="core-concepts-pylate-and-colbert-explained" class="level2">
<h2 class="anchored" data-anchor-id="core-concepts-pylate-and-colbert-explained">Core Concepts: PyLate and ColBERT Explained</h2>
<p><strong>PyLate</strong> is a Python library for vector retrieval and search, specifically designed for ColBERT models. It provides tools for indexing documents, encoding queries, and performing similarity search.</p>
<p><strong>ColBERT</strong> (Contextualized Late Interaction over BERT) creates dense vector representations for documents and queries, then uses late interaction (token-level matching) for retrieval instead of single vector similarity. This approach is faster and more efficient than traditional dense retrieval.</p>
</section>
<section id="dataset-formats" class="level2">
<h2 class="anchored" data-anchor-id="dataset-formats">Dataset Formats</h2>
<section id="format-1-tripletmulti-negative-format" class="level3">
<h3 class="anchored" data-anchor-id="format-1-tripletmulti-negative-format">Format 1: Triplet/Multi-negative Format</h3>
<p><strong>Q: What does triplet format look like?</strong> A: Each row contains: - <code>query</code>: The search query - <code>positive</code>: One relevant document - <code>negative1</code>, <code>negative2</code>, …: Multiple irrelevant documents</p>
<p><strong>Pros</strong>: Good for training with hard negatives <strong>Cons</strong>: No separate corpus, harder to evaluate</p>
</section>
<section id="format-2-structured-retrieval-format" class="level3">
<h3 class="anchored" data-anchor-id="format-2-structured-retrieval-format">Format 2: Structured Retrieval Format</h3>
<p><strong>Q: What does structured format contain?</strong> A: Three separate components: - <code>corpus</code>: All documents with IDs - <code>queries</code>: All queries with IDs - <code>qrels</code>: Relevance judgments (query-doc pairs)</p>
<p><strong>Pros</strong>: Standard IR evaluation format, works with PyLate directly <strong>Cons</strong>: More complex structure</p>
</section>
<section id="format-3-passage-ranking-format" class="level3">
<h3 class="anchored" data-anchor-id="format-3-passage-ranking-format">Format 3: Passage Ranking Format</h3>
<p><strong>Q: How does passage ranking format work?</strong> A: Each row has: - <code>query_id</code>, <code>query</code>: Query information - <code>positive_passages</code>: List of relevant documents - <code>negative_passages</code>: List of irrelevant documents</p>
<p><strong>Pros</strong>: Multiple positives/negatives per query, rich annotations <strong>Cons</strong>: Requires extraction to create corpus</p>
</section>
</section>
<section id="data-conversion-strategies" class="level2">
<h2 class="anchored" data-anchor-id="data-conversion-strategies">Data Conversion Strategies</h2>
<section id="memory-efficient-file-writing" class="level3">
<h3 class="anchored" data-anchor-id="memory-efficient-file-writing">Memory-Efficient File Writing</h3>
<p><strong>Q: How do you handle large datasets efficiently?</strong> A: Stream processing with direct file writing:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb1-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">with</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">open</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'corpus.jsonl'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'w'</span>) <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> f:</span>
<span id="cb1-2">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> el <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> dataset[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'corpus'</span>]:</span>
<span id="cb1-3">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> el[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'corpus-id'</span>] <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> el[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'text'</span>]:</span>
<span id="cb1-4">            json.dump({<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"_id"</span>: el[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'corpus-id'</span>], <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"text"</span>: el[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'text'</span>]}, f)</span>
<span id="cb1-5">            f.write(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>)</span></code></pre></div></div>
<p><strong>Pros</strong>: Low memory usage, handles any dataset size <strong>Cons</strong>: Requires file I/O, slightly slower</p>
</section>
<section id="pylate-file-requirements" class="level3">
<h3 class="anchored" data-anchor-id="pylate-file-requirements">PyLate File Requirements</h3>
<p><strong>Q: What files does BEIR datasets is ?</strong> A: - <code>corpus.jsonl</code>: <code>{"_id": "doc1", "text": "document text"}</code> - <code>queries.jsonl</code>: <code>{"_id": "q1", "text": "query text"}</code> - <code>qrels/split.tsv</code>: <code>query_id\tdoc_id\tscore</code></p>
<p><strong>Critical</strong>: File names and folder structure must match exactly</p>
</section>
<section id="direct-dictionary-conversion" class="level3">
<h3 class="anchored" data-anchor-id="direct-dictionary-conversion">Direct Dictionary Conversion</h3>
<p><strong>Q: How do you convert without files?</strong> A: Transform to PyLate’s expected return format:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb2-1">documents <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [{<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"id"</span>: doc_id, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"text"</span>: text} <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> doc_id, text <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> corpus.items()]</span>
<span id="cb2-2">queries <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">list</span>(queries.values())</span>
<span id="cb2-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># qrels stays as dictionary</span></span></code></pre></div></div>
<p><strong>Pros</strong>: Faster, no file operations <strong>Cons</strong>: Must match exact format, harder to debug</p>
</section>
</section>
<section id="evaluation-approaches" class="level2">
<h2 class="anchored" data-anchor-id="evaluation-approaches">Evaluation Approaches</h2>
<section id="custom-evaluation-with-ranx" class="level3">
<h3 class="anchored" data-anchor-id="custom-evaluation-with-ranx">Custom Evaluation with ranx</h3>
<p><strong>Q: When do you use ranx for evaluation?</strong> A: When you have non-standard formats or want custom metrics:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb3-1">qrels <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Qrels(qrels_dict)</span>
<span id="cb3-2">run <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Run(run_dict)</span>
<span id="cb3-3">metrics <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> evaluate(qrels, run, [<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ndcg@5"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"map@5"</span>])</span></code></pre></div></div>
<p><strong>Pros</strong>: Flexible, works with any format <strong>Cons</strong>: Manual setup required</p>
</section>
<section id="pylate-built-in-evaluation" class="level3">
<h3 class="anchored" data-anchor-id="pylate-built-in-evaluation">PyLate Built-in Evaluation</h3>
<p><strong>Q: When do you use PyLate’s evaluation?</strong> A: When data is in standard BEIR format with proper file structure</p>
<p><strong>Pros</strong>: Standardized, less code <strong>Cons</strong>: Strict format requirements</p>
</section>
</section>
<section id="indexing-strategies" class="level2">
<h2 class="anchored" data-anchor-id="indexing-strategies">Indexing Strategies</h2>
<section id="plaid-index" class="level3">
<h3 class="anchored" data-anchor-id="plaid-index">PLAID Index</h3>
<p><strong>Q: What is PLAID indexing?</strong> A: PyLate’s efficient indexing method for ColBERT embeddings, supporting fast similarity search</p>
<p><strong>Key Parameters</strong>: - <code>index_folder</code>: Where to store index - <code>index_name</code>: Identifier for the index - <code>override=True</code>: Overwrites existing index</p>
</section>
<section id="document-processing" class="level3">
<h3 class="anchored" data-anchor-id="document-processing">Document Processing</h3>
<p><strong>Q: How do you prepare documents for indexing?</strong> A: 1. Extract unique documents from all sources 2. Create document IDs and embeddings 3. Add to index with <code>add_documents()</code></p>
<p><strong>Important</strong>: Use <code>is_query=False</code> for documents, <code>is_query=True</code> for queries</p>
</section>
</section>
<section id="common-pitfalls-solutions" class="level2">
<h2 class="anchored" data-anchor-id="common-pitfalls-solutions">Common Pitfalls &amp; Solutions</h2>
<section id="file-format-issues" class="level3">
<h3 class="anchored" data-anchor-id="file-format-issues">File Format Issues</h3>
<p><strong>Q: What are common file format mistakes?</strong> A: - Wrong file extensions (.csv instead of .tsv) - Incorrect folder structure (missing qrels folder) - Wrong field names (<code>id</code> vs <code>_id</code>)</p>
</section>
<section id="data-extraction-problems" class="level3">
<h3 class="anchored" data-anchor-id="data-extraction-problems">Data Extraction Problems</h3>
<p><strong>Q: How do you handle variable-length lists?</strong> A: Use nested loops for negative passages:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb4-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> row <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> dataset:</span>
<span id="cb4-2">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> neg_doc <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'negative_passages'</span>]:</span>
<span id="cb4-3">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># process each negative document</span></span></code></pre></div></div>
</section>
<section id="memory-management" class="level3">
<h3 class="anchored" data-anchor-id="memory-management">Memory Management</h3>
<p><strong>Q: How do you avoid memory issues?</strong> A: - Process datasets in chunks - Use generators instead of lists - Write to files incrementally - Use dictionaries to avoid duplicates</p>
</section>
</section>
<section id="performance-considerations" class="level2">
<h2 class="anchored" data-anchor-id="performance-considerations">Performance Considerations</h2>
<section id="batch-processing" class="level3">
<h3 class="anchored" data-anchor-id="batch-processing">Batch Processing</h3>
<p><strong>Q: How do you optimize encoding speed?</strong> A: Use appropriate batch sizes: - Larger batches: Faster but more memory - Smaller batches: Slower but memory-safe - Typical: <code>batch_size=32</code> or <code>batch_size=64</code></p>
</section>
<section id="index-management" class="level3">
<h3 class="anchored" data-anchor-id="index-management">Index Management</h3>
<p><strong>Q: How do you manage multiple indexes?</strong> A: Use descriptive names and separate folders: - <code>index_folder="arabic_index"</code> - <code>index_name="gte-multilingual-base"</code></p>
</section>
</section>
<section id="evaluation-metrics" class="level2">
<h2 class="anchored" data-anchor-id="evaluation-metrics">Evaluation Metrics</h2>
<section id="standard-ir-metrics" class="level3">
<h3 class="anchored" data-anchor-id="standard-ir-metrics">Standard IR Metrics</h3>
<p><strong>Q: What metrics should you track?</strong> A: - <strong>NDCG@k</strong>: Normalized discounted cumulative gain - <strong>MAP@k</strong>: Mean average precision - <strong>Recall@k</strong>: Proportion of relevant docs retrieved - <strong>Precision@k</strong>: Proportion of retrieved docs that are relevant</p>
</section>
<section id="interpreting-results" class="level3">
<h3 class="anchored" data-anchor-id="interpreting-results">Interpreting Results</h3>
<p><strong>Q: What makes good retrieval performance?</strong> A: - NDCG@5 &gt; 0.7: Excellent - NDCG@5 &gt; 0.5: Good - NDCG@5 &gt; 0.3: Acceptable - NDCG@5 &lt; 0.3: Needs improvement</p>
<p>This comprehensive guide covers all the key concepts, trade-offs, and practical considerations for working with PyLate and ColBERT evaluation pipelines.</p>
<hr>
</section>
<section id="internal-resources" class="level3">
<h3 class="anchored" data-anchor-id="internal-resources">Internal Resources</h3>
<p>If you’re interested in more about vector retrieval and my AI research, explore these sections:</p>
<ul>
<li><a href="../../papers.html">My Research Papers</a></li>
<li><a href="../../oss/opensource.html">Open Source Contributions</a></li>
<li><a href="../../til/index.html">Today I Learned Index</a></li>
<li><a href="../../blog/feed.html">Main Blog Index</a></li>
</ul>


</section>
</section>
</section>

 ]]></description>
  <category>blogging</category>
  <category>til</category>
  <guid>https://kareemai.com/til/tils/2025-05-28-til.html</guid>
  <pubDate>Tue, 27 May 2025 21:00:00 GMT</pubDate>
  <media:content url="https://kareemai.com/til/tils/til.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>Meta’s RAPTOR RAG, DFloat11 Compression &amp; Pyrefly Guide</title>
  <dc:creator>kareem </dc:creator>
  <link>https://kareemai.com/til/tils/2025-05-25-til.html</link>
  <description><![CDATA[ 





<section id="rag-raptor-dfloat11-and-pyrefly-metas-latest-open-source-tools" class="level2">
<h2 class="anchored" data-anchor-id="rag-raptor-dfloat11-and-pyrefly-metas-latest-open-source-tools">RAG RAPTOR, DFloat11 and Pyrefly: Meta’s Latest Open Source Tools</h2>
<p>Over the last 2 days, I’ve been exploring some fascinating new open source tools from Meta and other organizations. These tools are revolutionizing how we approach RAG (Retrieval-Augmented Generation), model compression, and Python development. Let me break down what I’ve learned:</p>
<ol type="1">
<li><strong>RAPTOR RAG</strong> - Meta’s tree-based retrieval technique</li>
<li><strong>DFloat11</strong> - Lossless compression for LLMs</li>
<li><strong>Pyrefly</strong> - Fast Python type checker in Rust</li>
<li><strong>FastEmbed</strong> - Efficient embedding generation</li>
</ol>
</section>
<section id="what-is-raptor-rag-complete-guide-to-metas-raptor-technique" class="level2">
<h2 class="anchored" data-anchor-id="what-is-raptor-rag-complete-guide-to-metas-raptor-technique">What is RAPTOR RAG? Complete Guide to Meta’s RAPTOR Technique</h2>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://kareemai.com/til/tils/images/raptor.png" class="img-fluid figure-img"></p>
<figcaption>raptor rag</figcaption>
</figure>
</div>
<p>RAPTOR RAG is Meta’s innovative technique designed to improve document retrieval performance. While they claim a 20% improvement, my testing shows mixed results depending on the use case.</p>
<section id="understanding-raptor-rag" class="level3">
<h3 class="anchored" data-anchor-id="understanding-raptor-rag">Understanding RAPTOR RAG</h3>
<p><strong>RAPTOR</strong> stands for “Recursive Abstractive Processing for Tree-Organized Retrieval.” It’s a tree-based approach that constructs hierarchical representations of your documents by recursively clustering text chunks based on their vector embeddings and generating summaries of those clusters.</p>
<p>The core innovation is building a tree structure from the bottom up, which helps solve the fundamental limitation of traditional RAG systems: retrieving only a few short, contiguous text chunks that limit their ability to represent large-scale discourse structure.</p>
</section>
<section id="the-problem-raptor-rag-solves" class="level3">
<h3 class="anchored" data-anchor-id="the-problem-raptor-rag-solves">The Problem RAPTOR RAG Solves</h3>
<p>Traditional RAG systems struggle with thematic questions that require integrating knowledge from multiple parts of a document. This is particularly relevant for complex queries like understanding an entire book or analyzing long-form content.</p>
<p><strong>Example:</strong> Consider the fairy tale of Cinderella and the question “How did Cinderella reach her happy ending?” Traditional RAG’s top-k retrieved short contiguous texts won’t contain enough context to answer this comprehensively.</p>
</section>
<section id="how-raptor-rag-works" class="level3">
<h3 class="anchored" data-anchor-id="how-raptor-rag-works">How RAPTOR RAG Works</h3>
<p>RAPTOR solves this by using a tree structure to capture both high-level and low-level details about text. The process involves:</p>
<ol type="1">
<li><strong>Clustering text chunks</strong> based on semantic similarity</li>
<li><strong>Generating summaries</strong> for each cluster using language models</li>
<li><strong>Repeating the process</strong> recursively to build a hierarchical tree</li>
<li><strong>Tree-based retrieval</strong> during query time</li>
</ol>
</section>
<section id="model-based-summarization-in-raptor" class="level3">
<h3 class="anchored" data-anchor-id="model-based-summarization-in-raptor">Model-Based Summarization in RAPTOR</h3>
<p>After clustering nodes using Gaussian Mixture Models, each cluster is sent to a language model (typically GPT-3.5-turbo) for summarization. This step transforms large chunks of text into concise, coherent summaries, condensing potentially large volumes of retrieved information into manageable sizes.</p>
</section>
<section id="querying-raptor-rag" class="level3">
<h3 class="anchored" data-anchor-id="querying-raptor-rag">Querying RAPTOR RAG</h3>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://kareemai.com/til/tils/images/raptor_query.png" class="img-fluid figure-img"></p>
<figcaption>query RAPTOR rag</figcaption>
</figure>
</div>
<p>RAPTOR supports two main querying approaches:</p>
<ol type="1">
<li><strong>Tree Traversal</strong> - Navigate through the hierarchical structure</li>
<li><strong>Collapsed Tree Retrieval</strong> - Flatten the tree for faster retrieval</li>
</ol>
</section>
<section id="raptor-rag-performance-analysis" class="level3">
<h3 class="anchored" data-anchor-id="raptor-rag-performance-analysis">RAPTOR RAG Performance Analysis</h3>
<p>While the 20% improvement claim is appealing, my testing reveals some limitations:</p>
<ul>
<li><strong>Accuracy gains are marginal</strong> compared to SBERT-based solutions</li>
<li><strong>Computational overhead</strong> is significant for creation and retrieval</li>
<li><strong>Best use case</strong> is document summarization rather than question answering</li>
<li><strong>Information flow</strong> can be repetitive in some scenarios</li>
</ul>
</section>
<section id="raptor-rag-for-document-summarization" class="level3">
<h3 class="anchored" data-anchor-id="raptor-rag-for-document-summarization">RAPTOR RAG for Document Summarization</h3>
<p>The most compelling use case for RAPTOR is document summarization. By having detailed, medium, and high-level information representations, you can create better summaries by:</p>
<ul>
<li><strong>Dividing the summarization task</strong> across multiple levels</li>
<li><strong>Pre-computing summaries</strong> at different granularities</li>
<li><strong>Reducing the burden</strong> on the final LLM for summary generation</li>
</ul>
</section>
</section>
<section id="dfloat11-efficient-lossless-compression-for-llms" class="level2">
<h2 class="anchored" data-anchor-id="dfloat11-efficient-lossless-compression-for-llms">DFloat11: Efficient, Lossless Compression for LLMs</h2>
<p>DFloat11 (DF11) is a novel, mathematically lossless compression technique that reduces large language model memory usage by about 30% with zero accuracy loss. Unlike traditional quantization methods that can degrade model quality, DF11 uses Huffman coding to compress only the predictable exponent bits of model weights.</p>
<section id="how-dfloat11-works" class="level3">
<h3 class="anchored" data-anchor-id="how-dfloat11-works">How DFloat11 Works</h3>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://kareemai.com/til/tils/images/df11.png" class="img-fluid figure-img"></p>
<figcaption>DFloat11 encoding</figcaption>
</figure>
</div>
<p>DFloat11’s compression strategy is elegant in its simplicity:</p>
<ul>
<li><strong>Sign and Fraction Bits:</strong> Kept unchanged as they contain high-entropy information</li>
<li><strong>Exponent Bits:</strong> Compressed using a precomputed Huffman tree, replacing the fixed 8-bit exponent with variable-length codes</li>
<li><strong>Average Savings:</strong> About 5 bits per weight on average</li>
</ul>
</section>
<section id="dfloat11-storage-and-decoding" class="level3">
<h3 class="anchored" data-anchor-id="dfloat11-storage-and-decoding">DFloat11 Storage and Decoding</h3>
<p><strong>Storage Architecture:</strong> - Sign/fraction and exponent bits stored separately - Small header containing the Huffman codebook - Efficient packing for minimal overhead</p>
<p><strong>Runtime Decoding:</strong> - Original weights quickly reconstructed by combining sign/fraction block with decoded exponent - Enables fast, parallel processing on GPUs - No performance penalty during inference</p>
</section>
<section id="dfloat11-key-benefits" class="level3">
<h3 class="anchored" data-anchor-id="dfloat11-key-benefits">DFloat11 Key Benefits</h3>
<ul>
<li><strong>30% reduction</strong> in model size compared to bf16</li>
<li><strong>100% identical accuracy</strong> to the original model</li>
<li><strong>Universal applicability</strong> to any transformer-based LLM</li>
<li><strong>Zero training required</strong> - works with existing models</li>
</ul>
</section>
</section>
<section id="pyrefly-fast-python-type-checker-in-rust" class="level2">
<h2 class="anchored" data-anchor-id="pyrefly-fast-python-type-checker-in-rust">Pyrefly: Fast Python Type Checker in Rust</h2>
<p>Pyrefly is a blazingly fast Python type checker written in Rust, designed to provide near-instantaneous type checking for large Python codebases.</p>
<section id="installing-pyrefly-with-vs-code" class="level3">
<h3 class="anchored" data-anchor-id="installing-pyrefly-with-vs-code">Installing Pyrefly with VS Code</h3>
<p>I installed Pyrefly into VS Code and tested it with several projects including LlamaIndex and TypeCodebase. The experience was impressive:</p>
<ul>
<li><strong>Lightning-fast type checking</strong> compared to traditional tools</li>
<li><strong>Seamless VS Code integration</strong> with real-time feedback</li>
<li><strong>Excellent performance</strong> on large codebases</li>
<li><strong>Rust-powered reliability</strong> with minimal memory usage</li>
</ul>
</section>
<section id="pyrefly-vs-traditional-type-checkers" class="level3">
<h3 class="anchored" data-anchor-id="pyrefly-vs-traditional-type-checkers">Pyrefly vs Traditional Type Checkers</h3>
<p>Pyrefly’s Rust implementation provides significant advantages:</p>
<ul>
<li><strong>Speed improvements</strong> of 10-100x over Python-based type checkers</li>
<li><strong>Lower memory footprint</strong> for large projects</li>
<li><strong>Better error reporting</strong> with precise location information</li>
<li><strong>Incremental checking</strong> for faster subsequent runs</li>
</ul>
</section>
</section>
<section id="llamaindex-raptor-integration" class="level2">
<h2 class="anchored" data-anchor-id="llamaindex-raptor-integration">LlamaIndex RAPTOR Integration</h2>
<p>For those using LlamaIndex, RAPTOR RAG can be integrated to improve document retrieval performance. The tree-based approach works particularly well with LlamaIndex’s document processing pipeline.</p>
<section id="implementation-considerations" class="level3">
<h3 class="anchored" data-anchor-id="implementation-considerations">Implementation Considerations</h3>
<p>When implementing RAPTOR with LlamaIndex:</p>
<ul>
<li><strong>Consider the computational cost</strong> of building the tree structure</li>
<li><strong>Evaluate performance gains</strong> for your specific use case</li>
<li><strong>Test with your document types</strong> before full deployment</li>
<li><strong>Monitor memory usage</strong> during tree construction</li>
</ul>
</section>
</section>
<section id="meta-pyrefly-and-open-source-ecosystem" class="level2">
<h2 class="anchored" data-anchor-id="meta-pyrefly-and-open-source-ecosystem">Meta Pyrefly and Open Source Ecosystem</h2>
<p>Meta’s contribution to the Python development ecosystem through Pyrefly demonstrates their commitment to developer productivity. The combination of Rust’s performance with Python’s flexibility creates a powerful tool for modern development workflows.</p>
</section>
<section id="conclusion" class="level2">
<h2 class="anchored" data-anchor-id="conclusion">Conclusion</h2>
<p>These three tools represent significant advances in their respective domains:</p>
<ul>
<li><strong>RAPTOR RAG</strong> offers a novel approach to document retrieval, though with mixed practical benefits</li>
<li><strong>DFloat11</strong> provides genuine value for LLM deployment with lossless compression</li>
<li><strong>Pyrefly</strong> delivers substantial performance improvements for Python type checking</li>
</ul>
<p>While RAPTOR RAG’s claims may be overstated, the underlying tree-based approach shows promise for specific use cases like document summarization. DFloat11 and Pyrefly, however, offer clear, measurable benefits that make them valuable additions to any ML or Python development toolkit.</p>
</section>
<section id="references" class="level2">
<h2 class="anchored" data-anchor-id="references">References</h2>
<ol type="1">
<li><a href="https://xmad.ai">XMad Team Blog</a> - Meta’s research team insights</li>
<li><a href="https://arxiv.org/html/2401.18059v1">RAPTOR Paper</a> - Original research paper</li>
<li><a href="https://pyrefly.org/">Pyrefly Official Site</a> - Documentation and installation</li>
<li><a href="https://arxiv.org/abs/2406.02359">DFloat11 Research</a> - Compression technique details</li>
<li><a href="https://docs.llamaindex.ai/">LlamaIndex Documentation</a> - RAG framework integration</li>
</ol>
<hr>
<section id="internal-resources" class="level3">
<h3 class="anchored" data-anchor-id="internal-resources">Internal Resources</h3>
<p>If you’re interested in more about AI engineering and my research, explore these sections:</p>
<ul>
<li><a href="../../papers.html">My Research Papers</a></li>
<li><a href="../../oss/opensource.html">Open Source Contributions</a></li>
<li><a href="../../til/index.html">Today I Learned Index</a></li>
<li><a href="../../blog/feed.html">Main Blog Index</a></li>
</ul>


</section>
</section>

 ]]></description>
  <category>blogging</category>
  <category>til</category>
  <category>machine-learning</category>
  <category>python</category>
  <category>rag</category>
  <guid>https://kareemai.com/til/tils/2025-05-25-til.html</guid>
  <pubDate>Sat, 24 May 2025 21:00:00 GMT</pubDate>
  <media:content url="https://kareemai.com/til/tils/images/raptor.png" medium="image" type="image/png" height="47" width="144"/>
</item>
<item>
  <title>Does Brave Leo Run Locally? Privacy-First AI with Ollama and BYOM</title>
  <dc:creator>kareem </dc:creator>
  <link>https://kareemai.com/til/tils/2025-05-23-til.html</link>
  <description><![CDATA[ 





<section id="whats-brave-leo-ai-all-about" class="level2">
<h2 class="anchored" data-anchor-id="whats-brave-leo-ai-all-about">What’s Brave Leo AI All About?</h2>
<p><strong>Yes—Brave Leo runs locally and privately.</strong> Brave Leo AI is a privacy-first AI assistant built directly into the Brave browser. Unlike cloud-based AI assistants, Leo processes requests through anonymous relays and stores your chat history only on your device—never on Brave’s servers.</p>
<p>It works on macOS, Windows, Linux, Android, and iOS. Best part? No sign-up required to use it for free, and with the “Bring Your Own Model” (BYOM) feature, you can connect your own local LLMs like Ollama, vLLM, or SGLang for complete control over your AI experience.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://kareemai.com/til/tils/images/brave_leo.png" class="img-fluid figure-img"></p>
<figcaption>Brave Leo with Ollama or VLLM</figcaption>
</figure>
</div>
<section id="what-can-brave-leo-ai-do" class="level3">
<h3 class="anchored" data-anchor-id="what-can-brave-leo-ai-do">What Can Brave Leo AI Do?</h3>
<p>Leo’s got a lot of tricks up its sleeve: - <strong>Summarize Stuff Instantly</strong>: It can give you quick summaries of webpages, PDFs, Google Docs, Google Sheets, or even YouTube videos by reading their transcripts.</p>
<ul>
<li><p><strong>Answer Questions</strong>: Whether it’s about a webpage or just something you’re curious about, Leo can explain things clearly and even offer different perspectives.</p></li>
<li><p><strong>Write and Create</strong>: Need an article, email, essay, or some code? Leo can whip it up for you.</p></li>
<li><p><strong>Translate and Code</strong>: It can translate text into different languages or help with coding by suggesting or generating code snippets.</p></li>
<li><p><strong>Custom AI Models</strong>: With the “Bring Your Own Model” feature, you can plug in your own local or remote AI models for a personalized experience.</p></li>
</ul>
</section>
<section id="is-brave-leo-safe-to-use" class="level3">
<h3 class="anchored" data-anchor-id="is-brave-leo-safe-to-use">Is Brave Leo Safe to Use?</h3>
<p>Privacy is Leo’s middle name! Here’s why it’s safe:</p>
<ul>
<li><p><strong>Anonymized Requests</strong>: Leo uses a reverse proxy, so Brave can’t tie your requests to your IP address.</p></li>
<li><p><strong>No Chat Storage</strong>: Your conversations aren’t saved on Brave’s servers or used to train AI models.</p></li>
<li><p><strong>No Sign-Up Needed</strong>: You can use it for free without an account. Even the premium version uses anonymous tokens to keep things private.</p></li>
<li><p><strong>Local Storage</strong>: Your chat history stays on your device, and you can clear it anytime through the browser settings.</p></li>
<li><p><strong>Heads-Up on Third-Party Models</strong>: If you use external AI models (like Anthropic’s Claude), their data policies might differ (Claude keeps chats for 30 days, for</p></li>
<li><p>example). Always check the privacy terms if you go that route.</p></li>
</ul>
</section>
<section id="what-about-your-chat-history-with-leo" class="level3">
<h3 class="anchored" data-anchor-id="what-about-your-chat-history-with-leo">What About Your Chat History with Leo?</h3>
<p>If you’re using Brave version 1.75 or higher on desktop or Android (not in Incognito or Tor mode), you can keep track of your chats with Leo.</p>
<p>They’re stored locally on your device, not on any server, so you’re in control. You can revisit, continue, or delete them from the Leo full-page view (brave://leo-ai) or the browser’s sidebar.</p>
<p>Just note that clearing your browsing history will also wipe out any webpage-related content in your chats. Easy peasy!</p>
</section>
</section>
<section id="bring-your-own-model-byom-with-brave-leo" class="level2">
<h2 class="anchored" data-anchor-id="bring-your-own-model-byom-with-brave-leo">Bring Your Own Model (BYOM) with Brave Leo</h2>
<p>With <a href="https://support.brave.com/hc/en-us/articles/34070140231821-How-do-I-use-the-Bring-Your-Own-Model-BYOM-with-Brave-Leo">BYOM</a> , you can connect your own AI models to Leo for a custom experience. You can use platforms like vLLM, SGLang, or any inefernce engines with any Hugging Face Transformers model, as long as it follows the OpenAI Chat Protocol.</p>
<p>For example, you can run a model like Qwen2.5-VL-3B-Instruct locally with this command:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb1-1"></span>
<span id="cb1-2">python <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>m sglang.launch_server <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">--</span>port <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7501</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">--</span>model<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>path Qwen<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span>Qwen2<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">.5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>VL<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">B</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>Instruct</span></code></pre></div></div>
<p>This sets up a server for SGLang (or you can use vLLM with a similar command).</p>
<p>Then, in Brave Leo’s BYOM settings, add your model with these details:</p>
<p><strong>Label</strong>: Qwen2.5-VL-3B-Instruct</p>
<p><strong>Model Request Name</strong>: Qwen2.5</p>
<p><strong>Server Endpoint</strong>: http://127.0.0.1:7501/v1/chat/completions</p>
<p><strong>Context Size</strong>: 4000</p>
<p><strong>API Key</strong>: local</p>
<p><strong>System Prompt</strong>: A custom prompt like, “You are Leo, a helpful AI assistant by Brave. Provide clear, concise, polite responses under 80 words. Use a neutral tone, clarify if needed, and ensure accuracy.”</p>
<p>Brave doesn’t proxy these requests, so check the privacy terms of your chosen provider. Once set up, your model integrates with Leo, letting you use it directly in the browser for tailored, private AI chats. It’s like giving Leo your own custom brain!</p>
<hr>
<section id="internal-resources" class="level3">
<h3 class="anchored" data-anchor-id="internal-resources">Internal Resources</h3>
<p>If you’re interested in more about local LLMs and my AI research, explore these sections:</p>
<ul>
<li><a href="../../papers.html">My Research Papers</a></li>
<li><a href="../../oss/opensource.html">Open Source Contributions</a></li>
<li><a href="../../til/index.html">Today I Learned Index</a></li>
<li><a href="../../blog/feed.html">Main Blog Index</a></li>
</ul>


</section>
</section>

 ]]></description>
  <category>blogging</category>
  <category>til</category>
  <category>web</category>
  <category>ai</category>
  <category>llm</category>
  <category>local_llm</category>
  <category>ollama</category>
  <guid>https://kareemai.com/til/tils/2025-05-23-til.html</guid>
  <pubDate>Thu, 22 May 2025 21:00:00 GMT</pubDate>
  <media:content url="https://kareemai.com/til/tils/images/brave_leo.png" medium="image" type="image/png" height="71" width="144"/>
</item>
<item>
  <title>البوصلة الحقيقية: تأملات في تزكية النفس وإخلاص النية في طلب العلم</title>
  <dc:creator>kareem </dc:creator>
  <link>https://kareemai.com/til/tils/2025-05-21-til.html</link>
  <description><![CDATA[ 





<section id="السعي-الي-الكمال" class="level2">
<h2 class="anchored" data-anchor-id="السعي-الي-الكمال">السعي الي الكمال</h2>
<p>في الوقت الحالي .. أنا اقوم بالكثير من المشاريع ومنها الواعد الذي سيكون سبب في إدخال دخل مادي كبير و علمي إن شاء الله.</p>
<p>حاليا أعمل علي رسالة الماستر + عضو فعال في مجتمعين لتطوير البرمجيات والذكاء الإصطناعي في العالم العربي والإسلامي ولله الحمد والفضل وحده + أعمل في معمل باحثي تابع لاحد الأشخاص المميزة جدا و لدي أعمال باحثيه ومشاريع خاصه من نواحي متعددة.</p>
<p>أستشعر حاليا كثرة المهام والتشتت الكبير و قلة الوقت والمجهود والكثير ..لكن هذا ليس المشكلة. ما أستشعره هو زيادة الإعجاب بالنفس والبعد عن العبادة من أجل لذة العلم و حظ النفس.</p>
<p>و من داخلي لا أقنع بكل ما أقدم ..واري انه هناك المزيد من العلم والمعرفة يجب تحصليها و عدم الرضا بكوني مجرد مستقبل ومعدل لما أستقبله. مجال دراستي هو الذكاء والإصطناعي بتخصصاته و علوم الحاسب.</p>
<p>ما يزعجني الكثير ..منها لماذا أقوم باستقبال العلم من الخارج ولست أتحدث عن مجرد الشروحات الأجنبية و الأوراق والمشاريع البرمجية وكل هذا ولكن أتحدث عن الريادة في العلم ذاته. أتحدث عن أمثال جيفري هينتون وما بعده ..الرغبة في الوصول الي حافة العلم والإبداع وليس مجرد التعديل وفهم ما يصدرون.</p>
<p>هل أكتفي بهذا !</p>
<p>في الحقيقة لا اتذكر عندما تم إطلاق deepseek وقرات عن الشركة التي تقف ورائها..لماذا لم تكرر التجربة عربية إسلامية خالصة! ليس مستحيل تقنيا ونحن أولي بلغتنا وتراثنا من غيرنا من الشعوب خصوصا ..أن تكون هذه الشعوب لديها كراهية متشعبه خاصة لدينك وشعبك ولنا في فلسطين عبرة فيما يحدث فيها من تنكيل و جرائم لا احب حتي التفكر فيها. لكن ما يزيد الحزن والضعف والهم والغمة ..أن تجد من الريادة في مجالك و تخصصك أغلبهم من هولاء الصنف الذي يقتل إخوتك بدم بارد!</p>
<p>كيف تسعد نفسك وانت تابع لهولاء تنتظر منهم أن يعطوك بعض الفتتات من العلم لتذهب لتنتفخ به نفسك وتظن أن لديك شي من علم وهو فتات.</p>
<p>بداية من الباحثين لأصحاب الشركات للمواقع التي أقوم بالاستضافة عليها إلي الكورسات و مجتمعات التقنية..بل تزيد الحسرة عندي بحثي في بيانات لتطوير نموذج صغير لمهمة من مهام اللغة العربية أجد البيانات أين !ومن يعمل عليها !</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://kareemai.com/til/tils/images/isreal.png" class="img-fluid figure-img"></p>
<figcaption>الشعور بالعجز</figcaption>
</figure>
</div>
<p>يقومون بتجميع و تطوير نماذج تخدم فهم اللهجة الشامية تساعدهم في كل أعمالهم..وليس هذا وقت الحديث..</p>
<p>العوائق كثير مادية و معرفية وكثير لكن سقف الممكن مذهل..و هناك أمل و إن لم يكن يكفي أن تموت وانت تحاول وتنكر بقلبك وهذا أضعف الإيمان.</p>
</section>
<section id="البداية" class="level2">
<h2 class="anchored" data-anchor-id="البداية">البداية</h2>
<p>لدي من العمر الآن 22 عام لدي الكثير من الندم والحسرة علي العمر الفائت في غير الطاعة والعمل الصالح ووددت لو عندي فرصة في الرجوع للخلف كثيرا والبداية مجددا..لكننا لسنا في فيلم أنمي بل واقع…عزائي إنك إن تستدرك، تستدرك عند رب كريم قادر علي كل شئ. يبدل لك سيئاتك.</p>
<p>أعاني من الكثير من عسر الفهم في كل شئ تقريبا..خصوصا اللغة العربية لدي عسر قراءة و كتابة و الي الصف الثالث الثانوي لدي مشاكل فادحه في الكتابة..الإ أنني كنت احب الرياضيات برغم فشلي فيها ..واحب الإنجيليزي والحال أحسن من العربية بكثير ..احبهم ولكنهم لا يحبوني والحمد لله.</p>
<p>بدات أحاول جاهدا في الصف الثاني الثانوي محاولات تعتبر جاده الي الثالث الثانوي وكنت فاشله وتجاوزت الامتحانات بالغش ودخلت الجامعة ولا استحق هذا المكان ولا ذلك المجموع.</p>
<p>في كل تلك السنوات الفائته كنت تعيش في عالم المقارانات وتنتظر من الأهل و الأصحاب الإعتراف والتقدير ..برغم كل هذا فكنت أتلقي الكثير من الحب والإيمان بي من كل من درس لي تقريبا. فجزاهم الله خيرا.</p>
<p>من داخلي لأ افكر في هذه الأفكار كثيرا..لكني في بداية الجامعة تبدل الحال و أصبح كل وقتي تعلم ودراسة الي أن تخرجت العام الفائت و مررت بكثير من الصعاب وتجاوزتها و الحمد لله و الي الأن أقترب من اللحظة التي سيتغير فيها كل شئ ويتبدل كل الحال..من فرص السفر والمنح و نجاح الأعمال والحرية المادة و الكثير ثم قبلها يوم الحصاد أو يومها مثل أخر مره..أفقد كل هذا و أبدا من جديد..تشعر بالحزن كثيرا..لكن بعد فترة تجد رحمات ربك و تقديره في كل هذا و هناك أوقات لا تعرف ماهي الحكمة لكن تبدا في رؤية تقصيرك و تعيد حسابات وتتوجه الي الله مجددا.</p>
</section>
<section id="التحرر-من-الدنس" class="level2">
<h2 class="anchored" data-anchor-id="التحرر-من-الدنس">التحرر من الدنس</h2>
<p>بعد هذه السنين تنظر لنفسك و تبدا في الغوص في أعماك الذات لماذا أقوم بهذا وماهي الرغبة والهدف !</p>
<p>تجد أنك تم حبسك باستخدام معتقدات و أفكار سامة و فاسدة طيلة حياتك و القليل القلليل من الأفكار الصالحة من التربية و المجتمع…تأتي هذه الأفكار بعد أن تفككت الحياة وتبدلت وهناك الكثير من الموتي في حياتك وأنت مازلت</p>
<p>تعيش في سعيك للاعتراف بك…تعيش أسير للماضي فتظلم بذلك الحاضر والمستقبل.</p>
</section>
<section id="الأنانية-ولذة-العلم" class="level2">
<h2 class="anchored" data-anchor-id="الأنانية-ولذة-العلم">الأنانية ولذة العلم</h2>
<p>كان هناك أوقات يجب أن اختار المال أم العلم!وكنت بكل بساطة العلم ..فالمال سيأتي مستقبلا بعد العلم ..وهذا ليس صحيحا 100% ولكن الواقع مختلف..</p>
<p>لماذا تريد العلم!! أقوم بسرد المائات من الشعارات الجذابة عن العلم والتعلم والهمة ورفع الحرج عن الأمة والثغر وكلام يجعلك تقول ياه بارك الله فيك…</p>
<p>معظمه كلام ..لحظات الحقيقة هي المحن ..اللحظة التي سوف تتخلي عن عمل معين وسعي و لن يذكر اسمك ولكنه سيخرج باسم كلي وليس اسم يخصك فتشعر من داخلك ماذا لو كنت انا من قام به وحدي وتم ذكري اسمي وحدي علي منصاتي سوف أصبح معروفا في مجالي و احصل علي فرصة عمل جيدة….</p>
<p>لن أخبر هذا كيفية عمل النموذج هذا او أن هناك طريقة أسهل الي ان اقوم انا بها حتي يكون لي السبق!</p>
<p>والكثير من لحظات الانانية وحب الذات ولذة العلم تأتي علي حساب الغاية الاولي و مرضاة الله ، و حسن العلم والإخلاص في العمل والكثير من الثمرات التي أضيعها فأصبح عبدا للعبادة (طلب العلم ) ولست عبدا لله.</p>
</section>
<section id="هل-هذا-هو-الحق" class="level2">
<h2 class="anchored" data-anchor-id="هل-هذا-هو-الحق">هل هذا هو الحق؟</h2>
<p>الحمد لله الذي أراني بعض من أدناس القلب وفساد النية، هل هذا هو الحق! بالتاكيد لا.</p>
<p>ماهو الحق إذا…هناك الكثير من الإجابات لكن ما يحضر في قلبي حاليا بعد الحصول علي كثير من ما أحب من علم ومال و علاقات و غيره..أجد الإجابة القرانية هي الإجابة الوحيده الشافيه لتعبر عن ما أمر به من أزمة هوية حقيقة.</p>
<ul>
<li><strong>{ قُلْ هَلْ نُنَبِّئُكُمْ بِالأَخْسَرِينَ أَعْمَالا * الَّذِينَ ضَلَّ سَعْيُهُمْ فِي الْحَيَاةِ الدُّنْيَا وَهُمْ يَحْسَبُونَ أَنَّهُمْ يُحْسِنُونَ صُنْعًا }</strong> سورة الكهف.</li>
<li>سورة الحديد <iframe title="SoundCloud Audio Player" width="100%" height="300" scrolling="no" frameborder="no" allow="autoplay" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/301132298&amp;color=%23ff5500&amp;auto_play=false&amp;hide_related=false&amp;show_comments=true&amp;show_user=true&amp;show_reposts=false&amp;show_teaser=true&amp;visual=true"></iframe>
<div style="font-size: 10px; color: #cccccc;line-break: anywhere;word-break: normal;overflow: hidden;white-space: nowrap;text-overflow: ellipsis; font-family: Interstate,Lucida Grande,Lucida Sans Unicode,Lucida Sans,Garuda,Verdana,Tahoma,sans-serif;font-weight: 100;">
<a href="https://soundcloud.com/arwasharaqi" title="أرْوَى." target="_blank" style="color: #cccccc; text-decoration: none;">أرْوَى.</a> · <a href="https://soundcloud.com/arwasharaqi/al-7adeed" title="سورة الحديد - البراء بصفر" target="_blank" style="color: #cccccc; text-decoration: none;">سورة الحديد - البراء بصفر</a>
</div></li>
</ul>
<p>وليس عند ما يقال بعد سورة الحديد ومافيها من خطاب يحرك الصخر و يشفي الصدر و يعلي اللهمة ويعطي للعبد النظارة الحقيقة لرؤية الحق.</p>
</section>
<section id="طلب-التوفيق-و-الصلاح" class="level2">
<h2 class="anchored" data-anchor-id="طلب-التوفيق-و-الصلاح">طلب التوفيق و الصلاح</h2>
<p>في الحقيقة كل ما في الأعلي هو تمهيد أن كل أمالي و طموحاتي هي رغبة في المنافسة و الحصول علي التقدير والرفعة في الدينا…وهذا خسران مبين.</p>
<p>أرغب فعلا أن تكون تتحول هذه الرغبة الي رغبة فيما عند الله و محبتة و رضاه فهذا هو التوفيق و أن ترتفع درجاتي في الدنيا بأكبر قدر قبل فوات الأوان عندما تنقلب كل أعمالي الي حسرة و قبل أن يضل سعي و أنا أحسب أني احسن العمل.</p>
<p>بعد كل المصاعب التي تقابلني من حاجة مادة وحاجة للفهم والوقت والتوفيق والعلم و غير هذا..أجد أن الامر كله بيد الله و قدرته.</p>
<p><strong>فلا حول ولا قوة الإبالله و حسبي الله ونعم الوكيل.</strong></p>
<p>يجب علي تقبل المحدودية و الضعف و اللجوء الي من بيده ملكوت السموات و الأرض القادر علي كل شئ. سبحان ربي و تعالي و صلي الله وسلم علي سيدنا محمد.</p>
<hr>
<section id="مصادر-إضافية-من-الموقع" class="level3">
<h3 class="anchored" data-anchor-id="مصادر-إضافية-من-الموقع">مصادر إضافية من الموقع</h3>
<p>إذا كنت مهتماً بمتابعة رحلتي في هندسة الذكاء الاصطناعي ومعالجة اللغات الطبيعية، يمكنك زيارة الأقسام التالية:</p>
<ul>
<li><a href="../../papers.html">أبحاث في معالجة اللغة العربية</a></li>
<li><a href="../../oss/opensource.html">مشاريع مفتوحة المصدر</a></li>
<li><a href="../../til/index.html">مدونة “تعلمت اليوم” (TIL)</a></li>
<li><a href="../../blog/feed.html">فهرس المدونة التقنية</a></li>
</ul>


</section>
</section>

 ]]></description>
  <category>blogging</category>
  <category>til</category>
  <category>تزكيه</category>
  <guid>https://kareemai.com/til/tils/2025-05-21-til.html</guid>
  <pubDate>Tue, 20 May 2025 21:00:00 GMT</pubDate>
  <media:content url="https://kareemai.com/til/tils/images/isreal.png" medium="image" type="image/png" height="78" width="144"/>
</item>
<item>
  <title>How to Connect Porkbun Domains to Vercel and Cloudflare (Step-by-Step)</title>
  <dc:creator>Kareem </dc:creator>
  <link>https://kareemai.com/til/tils/2025-05-20-til.html</link>
  <description><![CDATA[ 





<section id="quick-faq-your-domain-setup-questions-answered" class="level2">
<h2 class="anchored" data-anchor-id="quick-faq-your-domain-setup-questions-answered">Quick FAQ: Your Domain Setup Questions Answered</h2>
<p><strong>Does Porkbun use Cloudflare?</strong> No, Porkbun is a domain registrar; Cloudflare is a DNS provider. You can use Porkbun’s built-in DNS <em>or</em> point Porkbun domains to Cloudflare’s nameservers for additional features (SSL, DDoS protection, faster propagation).</p>
<p><strong>How do I connect a Porkbun domain to Vercel?</strong> Add DNS records from Vercel to Porkbun’s DNS Management section. For Cloudflare routing: point Porkbun’s nameservers to Cloudflare, then add DNS records in Cloudflare.</p>
<p><strong>Why is Railway waiting for DNS updates?</strong> DNS changes can take 1-2 days to propagate globally. If it’s been longer, check that you’ve added the correct Records in Cloudflare and saved them.</p>
<p><strong>Can I migrate from Hostinger easily?</strong> Yes—disable WHOIS Privacy and Transfer Lock, get your Authorization Code, and submit to the new registrar (Porkbun).</p>
<hr>
</section>
<section id="managing-whois-privacy-during-transfer" class="level2">
<h2 class="anchored" data-anchor-id="managing-whois-privacy-during-transfer">Managing WHOIS Privacy During Transfer</h2>
<p>One critical setting often overlooked: <strong>WHOIS Privacy Protection</strong> (also called “Domain Privacy” in Vercel context).</p>
<p><strong>Before transferring from Hostinger:</strong> 1. Disable Privacy Protection (WHOIS Privacy)—this is required for the transfer 2. Wait for the status to update (usually instant, sometimes 12 hours) 3. Don’t re-enable WHOIS Privacy until after the transfer completes</p>
<p>With Porkbun, you can re-enable Domain Privacy after the transfer is complete for privacy protection.</p>
<p><strong>Why this matters</strong>: Vercel users often ask about WHOIS privacy—Vercel doesn’t manage WHOIS directly, but your registrar does. Keep this enabled for privacy unless you need your contact info public.</p>
<hr>
</section>
<section id="moving-my-domains" class="level2">
<h2 class="anchored" data-anchor-id="moving-my-domains">Moving My Domains</h2>
<p>I decided to transfer all 11 of my domains from Hostinger to other providers. I consulted two friends—a team lead in Canada and an SEO specialist in Turkey—and both recommended Porkbun.</p>
<p>I registered with Porkbun and was required to verify my identity. They offered multiple verification options, and I chose to use my government ID. However, I faced issues: I uploaded my ID about 10 times, and it failed every time, even though the verification platform supported my language. I reached out to their help center, and the fastest response came via email.</p>
<p>It took about 12 hours to receive a reply, which felt like a long time. The good news? They instantly verified my ID with no further issues. Later, when I asked another question, their response again took several hours, unlike Hostinger, which typically responds within 1 to 30 minutes (and at most within 2 hours). However, I found Hostinger’s customer service stricter and sometimes less friendly.</p>
<p>I’ll discuss my reasons for moving later, but for now, let’s focus on the process.</p>
<section id="moving-from-hostinger-to-porkbun" class="level3">
<h3 class="anchored" data-anchor-id="moving-from-hostinger-to-porkbun">Moving from Hostinger to Porkbun</h3>
<p>I had never transferred a domain before, so I expected it to be challenging. However, Hostinger made the process straightforward without asking why I was transferring.</p>
<p>Here’s how to do it:</p>
<ol type="1">
<li>Go to your Hostinger dashboard.</li>
<li>Disable the <strong>Privacy Protection (WHOIS Privacy Protection)</strong> button.</li>
<li>Disable the <strong>Transfer Lock</strong> button. This may take up to 12 hours to update.</li>
<li>Obtain the <strong>Authorization Code</strong> (EPP code) from the dashboard and save it, as you’ll need to provide it to Porkbun for the domain transfer.</li>
</ol>
<p>On Porkbun’s website: - Enter your domain name in the <strong>Domain Name</strong> field under the transfer section. - Copy the authorization code from Hostinger and paste it into the <strong>Auth Code</strong> field. - Click <strong>Submit</strong>.</p>
<p>The transfer(s) will be added to your cart. From there, click <strong>Continue to Billing</strong> to pay for the transfer. It’s that simple!</p>
<p>If your domain is older than 60 days, the transfer typically takes 5 to 7 days. Some domains may transfer in as little as 2 days, but Hostinger will send a verification request via email to confirm the transfer.</p>
<p>Note: If your domain is less than 60 days old, you’ll need to wait until it passes the 60-day mark. There’s talk of this being reduced to 30 days, but as of this writing (May 2025), the 60-day rule applies, per ICANN regulations, not Hostinger or Porkbun.</p>
</section>
</section>
<section id="connecting-your-domain-vercel-railway-and-cloudflare-setup" class="level2">
<h2 class="anchored" data-anchor-id="connecting-your-domain-vercel-railway-and-cloudflare-setup">Connecting Your Domain: Vercel, Railway, and Cloudflare Setup</h2>
<section id="connecting-porkbun-domains-to-vercel" class="level3">
<h3 class="anchored" data-anchor-id="connecting-porkbun-domains-to-vercel">Connecting Porkbun Domains to Vercel</h3>
<p>Connecting a domain to Vercel is straightforward:</p>
<ol type="1">
<li>In Vercel’s dashboard, add your domain from Porkbun</li>
<li>Vercel shows you the DNS records to add</li>
<li>Go to Porkbun’s <strong>DNS Management</strong> section (from domain dashboard)</li>
<li>Add the records Vercel specifies</li>
<li>Wait 5-30 minutes for verification</li>
</ol>
</section>
<section id="using-cloudflare-with-vercel-and-porkbun" class="level3">
<h3 class="anchored" data-anchor-id="using-cloudflare-with-vercel-and-porkbun">Using Cloudflare with Vercel and Porkbun</h3>
<p>If you want Cloudflare’s features (DDoS protection, SSL, faster DNS):</p>
<ol type="1">
<li>Add your Porkbun domain to Cloudflare</li>
<li>Cloudflare shows you their nameservers</li>
<li>In Porkbun, update your domain’s nameservers to point to Cloudflare’s</li>
<li>Add your Vercel DNS records <em>inside Cloudflare</em> (not Porkbun)</li>
<li>Wait for nameserver propagation (1-2 hours typical, up to 48 hours)</li>
</ol>
</section>
<section id="setting-up-railway-with-cloudflare" class="level3">
<h3 class="anchored" data-anchor-id="setting-up-railway-with-cloudflare">Setting Up Railway with Cloudflare</h3>
<p>Railway also needs DNS records, but your domain needs to work with both Vercel <em>and</em> Railway:</p>
<ol type="1">
<li>Configure Cloudflare to manage your Porkbun domain (change nameservers in Porkbun)</li>
<li>Add Railway’s DNS records to Cloudflare (not Porkbun directly)</li>
<li>Add Vercel’s DNS records to Cloudflare as well</li>
<li>Both services now use Cloudflare’s DNS</li>
</ol>
</section>
<section id="troubleshooting-railway-waiting-for-dns-update" class="level3">
<h3 class="anchored" data-anchor-id="troubleshooting-railway-waiting-for-dns-update">Troubleshooting: “Railway Waiting for DNS Update”</h3>
<p>If you see this message:</p>
<ol type="1">
<li><strong>Check propagation</strong>: Use <a href="https://www.whatsmydns.net">whatsmydns.net</a> to verify your DNS records globally</li>
<li><strong>Wait longer</strong>: DNS changes can take 1-2 business days to fully propagate</li>
<li><strong>Verify records in Cloudflare</strong>: Make sure you added the exact records Railway specified</li>
<li><strong>Check nameservers</strong>: Ensure Porkbun’s nameservers still point to Cloudflare (not reverted)</li>
<li><strong>Refresh</strong>: Try removing and re-adding the domain in Railway after propagation is complete</li>
</ol>
<p>Most delays happen because: - Nameserver changes take time to propagate globally - Users add records to Porkbun when they should add them to Cloudflare - Records are added with typos (domain must match exactly)</p>
<hr>
</section>
</section>
<section id="why-i-switched-from-hostinger-to-porkbun" class="level2">
<h2 class="anchored" data-anchor-id="why-i-switched-from-hostinger-to-porkbun">Why I Switched from Hostinger to Porkbun</h2>
<section id="internal-resources" class="level3">
<h3 class="anchored" data-anchor-id="internal-resources">Internal Resources</h3>
<p>If you’re interested in more about web development and my AI research, explore these sections:</p>
<ul>
<li><a href="../../papers.html">My Research Papers</a></li>
<li><a href="../../oss/opensource.html">Open Source Contributions</a></li>
<li><a href="../../til/index.html">Today I Learned Index</a></li>
<li><a href="../../blog/feed.html">Main Blog Index</a></li>
</ul>


</section>
</section>

 ]]></description>
  <category>blogging</category>
  <category>til</category>
  <category>seo</category>
  <category>domains</category>
  <category>vercel</category>
  <category>porkbun</category>
  <category>web</category>
  <guid>https://kareemai.com/til/tils/2025-05-20-til.html</guid>
  <pubDate>Mon, 19 May 2025 21:00:00 GMT</pubDate>
  <media:content url="https://kareemai.com/til/tils/til.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>AI Research Blogging: Why Substack Matters for Researchers</title>
  <dc:creator>kareem </dc:creator>
  <link>https://kareemai.com/til/tils/2025-05-19-til.html</link>
  <description><![CDATA[ 





<section id="what-is-substack" class="level2">
<h2 class="anchored" data-anchor-id="what-is-substack">What is Substack?</h2>
<p>From their about page: “On Substack, writers and creators can publish their work and make money from paid subscriptions while supporters can directly sustain the work they deeply value.”</p>
<p>It’s a platform where you can publish what you want in an organized way, with great analytics tools and a powerful recommendation and search system.</p>
<p>I like to think of it as a nicer version of Medium, with more than just SEO dumped from Google.</p>
<p>I really love the network from a design perspective. It’s an organized recommendation system based on multiple aspects.</p>
</section>
<section id="why-use-substack-as-an-ai-researcher" class="level2">
<h2 class="anchored" data-anchor-id="why-use-substack-as-an-ai-researcher">Why use Substack as an AI Researcher?</h2>
<p>I used LinkedIn and Medium, and I don’t find them very useful for engagement or building a real network.</p>
<p>My gravity is very tiny in these networks and I can’t get bigger for multiple reasons I will discuss later.</p>
<p>The same is true for X, but it’s a very good place for the ML community.</p>
<p>My reasons:</p>
<ol type="1">
<li><p>Improve my writing style. I am not good at writing or English, but I am trying to do my best. Communication is a very important skill for my work as a researcher.</p></li>
<li><p>I build products I want people to learn more about…more later.</p></li>
<li><p>I have services I want to market…more later.</p></li>
</ol>
<p>Did you forget something?</p>
<p>^_^</p>
<p>Die, empty, and publish your knowledge!</p>
<p>Actually, the main reason for me to write is that I feel lonely in my journey of learning about DL and software engineering.</p>
<p>And I feel bored most of the time.</p>
<p>I love the feeling that I am writing and archiving my life. This reminds me that I am doing hard work, learning new things, and my life will not end without doing great things from my point of view.</p>
<p>Recapping what I learned when I write about it makes the concepts stick in your mind, and you get more insights from people’s comments. This is very helpful for me.</p>
<p>For readers, you can see what I do, and you may be interested in it, be inspired, and learn from my mistakes.</p>
<section id="following-the-giants" class="level3">
<h3 class="anchored" data-anchor-id="following-the-giants">Following the Giants?</h3>
<p>When I started learning about DL, I searched for a great book about DL and PyTorch that is well explained in both code and theory.</p>
<p>I found his Substack where he publishes what he learns. At the same time, I found similar people like</p>
<ul>
<li><p><a href="https://substack.com/@jayalammar">Jay Alammar</a></p></li>
<li><p><a href="https://newsletter.maartengrootendorst.com/">Maarten Grootendorst</a></p></li>
<li><p><a href="https://decodingml.substack.com/p/llm-engineers-handbook-is-finally">Paul Iusztin</a></p></li>
</ul>
<p>These people I follow and appreciate what they provide!</p>
<p>So I started to ask, why do they use Substack?</p>
<p>The answer is very clear if you know them ^_^</p>
</section>
<section id="quick-analysis" class="level3">
<h3 class="anchored" data-anchor-id="quick-analysis">Quick analysis</h3>
<p>The UI/UX, speed of the website, and animations are very cool.</p>
<p>Let’s look at the level I want to reach :)</p>
<section id="ahead-of-ai" class="level4">
<h4 class="anchored" data-anchor-id="ahead-of-ai">Ahead of AI</h4>
<p>On 28/04/2023</p>
<p>It reached 15,028 free subscribers and only 69 paid ones!</p>
<p>This is very disappointing for me.</p>
<p>You don’t know if these are monthly or yearly paid and how much they give.</p>
<p>Of course, I don’t know how much he earns or others. I want to motivate myself and not create high expectations. He is doing great stuff, really great. His content is in the top 5 for me for AI and real content.</p>
<p>No scams, no “read this paper,” “look at this book,” “here are the top 1000 chatbots that are better than 10 who are better than GPT!!”</p>
<p>Oh my god, QwenClaudeMixtral just released a model that will convert space into water in the year 1021932103120931920.</p>
<p>This is very silly if you respect your readers’ minds!</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://kareemai.com/til/tils/images/old_ahead_of_ai.jpg" class="img-fluid figure-img"></p>
<figcaption>Ahead of AI subscribers in 2024</figcaption>
</figure>
</div>
<p>What about now?</p>
<p>He has more than 105k+ and is #71 Rising in Technology. I don’t know why 71!! He must be top 5.</p>
<p><strong>Jay Alammar</strong> =&gt; 23k+ subscribers</p>
<p><strong>Maarten Grootendorst</strong> =&gt; 20k+ subscribers <strong>Paul Iusztin</strong> =&gt; 25k+ subscribers</p>
<p>Most likes per post are around 10 to 20 only!</p>
<p>The comments are around 0 to 5 :)</p>
</section>
</section>
<section id="my-goal-in-the-coming-6-months" class="level3">
<h3 class="anchored" data-anchor-id="my-goal-in-the-coming-6-months">My Goal in the coming 6 months?</h3>
<p>I am doing multiple things at the current time.</p>
<p>I am on 4 projects and doing my Master Thesis and a lot of projects and websites I am developing.</p>
<p>I will not be able to provide much, but I will try my best.</p>
<p>I don’t care about the number of subscribers, I care about real ones, who will comment and read the content. If I can get 30 people to read it, this is great. Really, if you imagine 30 people in your room watching what you did, it’s mind-blowing. Imagine 300 or 3,000…Wow.</p>
<p>For money, if I can get only $200 per month, this is very great as a start.</p>
<section id="disease-from-other-websites" class="level4">
<h4 class="anchored" data-anchor-id="disease-from-other-websites">Disease from other websites?</h4>
<p>I noticed the following issues on the first day:</p>
<ol type="1">
<li><p>Sh*** shorts and copyright issues: By copyright, I mean some people take others’ content from outside Substack and post it as if it is their own and get followers for this! This is very bad. I don’t like strict copyright like “you copied this sentence” or “used a logo,” but stealing the whole content!!!</p></li>
<li><p>Very short articles compared to normal tweets! I found a lot of articles that appeared to me are like tweets…I thought I was in a place where people write in-depth content, not clickbait.</p></li>
</ol>
<p>I don’t talk about the post but the long-form ones.</p>
<ol start="3" type="1">
<li>Drop your Substack fake numbers: A lot of people post “drop your Substack below and whatever it’s about I will exchange” and multiple similar things!! What is the</li>
<li>purpose then… you have 1 million subscribers, then what?</li>
</ol>
</section>
<section id="there-is-no-official-api-for-substack" class="level4">
<h4 class="anchored" data-anchor-id="there-is-no-official-api-for-substack">There is no official API for Substack</h4>
<p>The most annoying thing in Substack is there is no current API to develop apps, create extensions, and automate a lot of things.</p>
</section>
</section>
<section id="what-things-can-i-write-about" class="level3">
<h3 class="anchored" data-anchor-id="what-things-can-i-write-about">What things can I write about?</h3>
<p>You seem to love to talk a lot? What will you write then?</p>
<p>It’s very obvious…</p>
<p>I want to talk about the following:</p>
<ol type="1">
<li><p>Compute world with AI, fine-tuning/training, and cloud instances, etc.</p></li>
<li><p>Products I use and tried, not product reviews.</p></li>
<li><p>Books and papers I read and summarized.</p></li>
<li><p>TILs, what I learned today!</p></li>
<li><p>Novel writing about the AI world like vector databases, embedding, and searching, etc.</p></li>
<li><p>Applications I build and services I provide.</p></li>
<li><p>My workflow and software i use.</p></li>
<li><p>Substack tips and analysis.</p></li>
</ol>
<p>you can find links here for now: 1. Gpuvec publications</p>
<iframe title="GPUVec Newsletter" src="https://gpuvecc.substack.com/embed" width="480" height="320" style="border:1px solid #EEE; background:white;" frameborder="0" scrolling="no">
</iframe>
<ol start="2" type="1">
<li>Kareem’s TILs</li>
</ol>
<iframe title="Kareem's Newsletter" src="https://kareemnns.substack.com/embed" width="480" height="320" style="border:1px solid #EEE; background:white;" frameborder="0" scrolling="no">
</iframe>
<hr>
</section>
<section id="internal-resources" class="level3">
<h3 class="anchored" data-anchor-id="internal-resources">Internal Resources</h3>
<p>If you’re interested in more about AI engineering and my research, explore these sections:</p>
<ul>
<li><a href="../../papers.html">My Research Papers</a></li>
<li><a href="../../oss/opensource.html">Open Source Contributions</a></li>
<li><a href="../../til/index.html">Today I Learned Index</a></li>
<li><a href="../../blog/feed.html">Main Blog Index</a></li>
</ul>


</section>
</section>

 ]]></description>
  <category>blogging</category>
  <category>til</category>
  <category>seo</category>
  <category>substack</category>
  <guid>https://kareemai.com/til/tils/2025-05-19-til.html</guid>
  <pubDate>Sun, 18 May 2025 21:00:00 GMT</pubDate>
  <media:content url="https://kareemai.com/til/tils/images/old_ahead_of_ai.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>Explore the Qdrant Blog core concepts | Part 1</title>
  <dc:creator>kareem </dc:creator>
  <link>https://kareemai.com/til/tils/2025-05-18-til.html</link>
  <description><![CDATA[ 





<section id="overview-of-qdrant-features-and-concepts" class="level2">
<h2 class="anchored" data-anchor-id="overview-of-qdrant-features-and-concepts">Overview of Qdrant features and Concepts</h2>
<p>I will divide the blogs into 3 types:</p>
<ol type="1">
<li><p>Startups using Qdrant: why and comparision you get read nice usecases with some numbers of comparision and how qdrant is amazing</p></li>
<li><p>Startup using Qdrant++: The same but with code snippets and System Design discussion..very useful for me as a developer</p></li>
<li><p>Qdrant releases: New features in Qdrant and how to use them.</p></li>
</ol>
<p><strong>Remember this when i will build Agentic RAG in the new job</strong></p>
<p>users tend to ask more structured, analytical questions when they know a database is involved—queries better suited to SQL than vector search. This prompted the team to pair Qdrant with a text-to-SQL system, blending unstructured and structured query capabilities for a more versatile agent.</p>
<section id="hotel-search-with-vectors" class="level3">
<h3 class="anchored" data-anchor-id="hotel-search-with-vectors">Hotel Search with Vectors</h3>
<p>Superlinked enhances search by embedding each attribute (text, numbers, categories) into specialized spaces, enabling nuanced, multi-attribute queries.</p>
<p>An LLM interprets user intent, assigning weights to preferences (e.g., price, rating), allowing flexible, business-driven ranking without system redesign.</p>
<p>Hard filters narrow results, while weighted nearest neighbor search ranks them by user preferences.</p>
<p>This unified approach supports multimodal search—combining semantic text, scaled numerical, and categorical data—preserving relationships and preference strengths.</p>
<p>Unlike traditional systems that separate or flatten data, Superlinked enables simultaneous, weighted consideration of all attributes, solving challenges like reconciling</p>
<p>results across types and capturing nuanced user intent.</p>
</section>
<section id="reciprocal-rank-rusion-rrf" class="level3">
<h3 class="anchored" data-anchor-id="reciprocal-rank-rusion-rrf">Reciprocal Rank Rusion (RRF)</h3>
<p>Qdrant’s native support for Reciprocal Rank Fusion (RRF) streamlined their retriever implementations, reducing hybrid search code by 80%. The multi-vector capabilities also enabled more sophisticated retrieval methods that better captured semantic relationships.</p>
</section>
<section id="qdrant-1.13-gpu-indexing" class="level3">
<h3 class="anchored" data-anchor-id="qdrant-1.13-gpu-indexing">Qdrant 1.13 GPU Indexing</h3>
<p>Here is summary of these new features</p>
<section id="gpu-accelerated-indexing-with-qdrant" class="level4">
<h4 class="anchored" data-anchor-id="gpu-accelerated-indexing-with-qdrant">GPU Accelerated Indexing with Qdrant</h4>
<p><strong>You can Index over all majro GPU vendors including NVIDIA,AMD and Intel that support Vulkan API to get speeds up to 10x faster than CPU-based methods</strong>*</p>
<p>As of right now this solution supports only on-premises deployments, but they will introduce support for Qdrant Cloud shortly.</p>
<p>Additional benefits:</p>
<ol type="1">
<li><p>Multi-GPU support</p></li>
<li><p>GPU indexing supports all quantization options and datatypes in Qdrant</p></li>
</ol>
</section>
<section id="strict-mode-for-opertional-control" class="level4">
<h4 class="anchored" data-anchor-id="strict-mode-for-opertional-control">Strict mode for Opertional Control</h4>
<p>Strict Mode enforces operational controls in distributed Qdrant deployments. It limits resource-intensive operations (like unindexed filtering and large batch sizes), sets boundaries on search parameters, and adds safeguards for payload sizes and timeouts. This prevents system overload, solves the “noisy neighbor” problem, and ensures reliable performance—especially in multi-tenant or serverless environments.</p>
</section>
<section id="hnsw-graph-compression" class="level4">
<h4 class="anchored" data-anchor-id="hnsw-graph-compression">HNSW Graph Compression</h4>
<p>Make search lighter on memory wihtout sacrificing speed with Delta Encoding.</p>
<p>Delta Encoding is a clever way to compress data by storing only the differences (or “deltas”) between values. It’s commonly used in search engines (for the classical inverted index) to save space and improve performance. <em>I think i have read this with Colbertv2 using similar techniques to reduce the siz </em> it’s called <strong>residual compression mechanism</strong> needs more searching</p>
<p>It’s now used for HNSW graph structure that powers Qdrant’s search.</p>
</section>
</section>
</section>
<section id="static-embedding-with-qdrant-and-model2vec" class="level2">
<h2 class="anchored" data-anchor-id="static-embedding-with-qdrant-and-model2vec">Static Embedding with Qdrant and Model2vec</h2>
<p>Static embedding from minishLab reduce the model size with 15x reduction and up to 500x speed increase while the maintain more than 85% of the performance levels. it’s like our <a href="https://kareemai.com/blog/posts/minishlab/zaraah.html">zaraah model</a> for arabic.</p>
<p>Static embedding are dense embedding so you can also use with qdrant collections. The retrieval is not going to be any faster becuase static embeddings. but the speedup is in creating the vectors from your data and encoding the queries.</p>
<p>If you want to make the retrieval faster use the following: 1. Matryoshka Embeddings 2. Quantization methods like (Scalar and Binary Quantization) ### When to use Static Embeddings ?</p>
<ol type="1">
<li><p><strong>Mobile applications</strong> - although many smartphones have powerful CPUs or even GPUs, the battery life is still a concern, and the static embeddings might be a good compromise between the quality and the power consumption. Moreover, the static embeddings can be used in the applications that require offline mode.</p></li>
<li><p><strong>Web browser extensions</strong> - running a transformer-based model in a web browser is usually not quite an option, but static embeddings might be a good choice, as they have fewer parameters and are faster to encode.</p></li>
<li><p><strong>Embedded systems</strong> - the static embeddings might be a good choice for the devices with limited computational power, such as IoT devices or microcontrollers.</p></li>
</ol>
<section id="references" class="level3">
<h3 class="anchored" data-anchor-id="references">References:</h3>
<p>There is more text in here from Qdrant not me..you can continue reading here</p>
<ol type="1">
<li><p><a href="https://qdrant.tech/blog/superlinked-multimodal-search/">Hotel Search</a></p></li>
<li><p><a href="https://qdrant.tech/blog/">Qdrant Blog</a></p></li>
<li><p><a href="https://qdrant.tech/blog/static-embeddings/">Static Embedding</a></p></li>
</ol>


</section>
</section>

 ]]></description>
  <category>blogging</category>
  <category>til</category>
  <category>qdrant</category>
  <guid>https://kareemai.com/til/tils/2025-05-18-til.html</guid>
  <pubDate>Sat, 17 May 2025 21:00:00 GMT</pubDate>
  <media:content url="https://kareemai.com/til/tils/til.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>Learning in Public: Why I Started My TIL Journey</title>
  <dc:creator>kareem </dc:creator>
  <link>https://kareemai.com/til/tils/2025-05-17-til.html</link>
  <description><![CDATA[ 





<section id="why-til" class="level2">
<h2 class="anchored" data-anchor-id="why-til">Why TIL ?</h2>
<p>It helps you overcome the perfacationsim in writting. you don’t need to create great article in depth about things you want to share or learn about..etc, all what you want it to write a thing you were trying to learn or solve today and how you solve it</p>
<p>which will help me more focused and make the process of learning more easier and useful for me and others</p>
</section>
<section id="create-your-own-gravitey" class="level2">
<h2 class="anchored" data-anchor-id="create-your-own-gravitey">create your own gravitey</h2>
<p>sometimes you want to reach and communicate with people in the same space of problems you are solving, search engines are very bad in provide the information you want..this is related to how these engines work and other SEO stuff. but for me, i can’t reach people and help them or get benefit from them because they simple don’t know about me!!</p>
<p>TIL will decreases this spaces and daily TIl about the things i am learning which are alot will start to give me nice SEO and unique because i am talking about things i don’t know and i am interested in and there will be much people in the same boat this will increase my X account and linkedin and this is very useful in the current time.</p>
</section>
<section id="tils-level-up" class="level2">
<h2 class="anchored" data-anchor-id="tils-level-up">TILs level up</h2>
<p>I also want to think in way to extract more crafted blogs from my TILs. but just start making it habbit and will see who will it comes in the end.</p>
<p>initial thoughts: 1. weekly recap from my TILs and SEO optimization for the keywords that is increasing and i am interested in 2. ML to extract related stuff, for example i will want to take about the folloinwg topics: - Late interaciton (Pylate, Colbertv2, ColPali) - Searching - Model2vec - Visino Language models..etc collecting them and start writing about them and adding internal links for them will be very useful to improve my blog system</p>
</section>
<section id="things-i-learned-the-last-2-days" class="level2">
<h2 class="anchored" data-anchor-id="things-i-learned-the-last-2-days">Things i learned the last 2 days</h2>
<section id="the-best-way-to-increase-traffic-is-comment-with-valuble-knowledge." class="level3">
<h3 class="anchored" data-anchor-id="the-best-way-to-increase-traffic-is-comment-with-valuble-knowledge.">The best way to increase traffic is comment with valuble knowledge.</h3>
<p>I was scorlling on X and found some popular account tweets about Harvard CS197 AI Research and i had create a review year ago about it I add the link in the comment and just slept. Boom i found reply analytics links opened wihtout annoying anyone!! - 501 Impressions - 77 Engagements - 2 profile visits - 74 clicks</p>
</section>
</section>
<section id="what-is-palid-index" class="level2">
<h2 class="anchored" data-anchor-id="what-is-palid-index">What is PALID index?</h2>
<p>PLAID index is for indexing very large datasets with Later interaction models like (Colbertv2 &amp; ColPali) IT Solves the storage footprint and allow you to scale to infinity</p>
<p>They swapped the faiss from facebook what is nice thing because i have multiple bad time to install it especially the GPU version.</p>
<p>and used fastkeamns from the amazing <span class="citation" data-cites="bclaive">@bclaive</span> which i really like his work on embeddings</p>
<p>It’s replacement for Voyager-based HNSW index which was very bad for scaling Late-Interaction retrieval models</p>
</section>
<section id="prime-intellect-vs-gpuvec" class="level2">
<h2 class="anchored" data-anchor-id="prime-intellect-vs-gpuvec">Prime Intellect VS Gpuvec</h2>
<p>I was creating a website to find and compare the cloud compute instances from all cloud providers in easy and interactive way.</p>
<p>I started to work on it the last month, but stoped for other work.</p>
<p>suddenly i found this website which is called Prime intellect.</p>
<p>And i just want to say,woooooow. it’s a piece of art. The design and information on it and how fast, accurate is very embrassing for my poor gpuvec.com</p>
<p>should i continue improve my website?</p>
<p>Actually yes, we share similar goals but there is multiple chances to compete or even collaborite!! who knows!</p>
<p>They are more than just listing and compare prices, then enable you to use these GPUs from their website.</p>
<p>Also they create decentralized models and have a mutliple expirened engineers.</p>
</section>
<section id="references" class="level2">
<h2 class="anchored" data-anchor-id="references">References</h2>
<ol type="1">
<li><a href="https://x.com/antoine_chaffin/status/1923378986219958526">Antoine tweet</a></li>
<li><a href="https://betatim.github.io/posts/til-explained/">betatim TIL</a></li>
<li><a href="https://kareemai.com/til/">other TILs</a></li>
</ol>


</section>

 ]]></description>
  <category>blogging</category>
  <category>til</category>
  <guid>https://kareemai.com/til/tils/2025-05-17-til.html</guid>
  <pubDate>Fri, 16 May 2025 21:00:00 GMT</pubDate>
  <media:content url="https://kareemai.com/til/tils/til.jpg" medium="image" type="image/jpeg"/>
</item>
</channel>
</rss>
