<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>源码阅读 on Hellokitty&#39;s Blog</title>
    <link>https://yangyang233333.github.io/categories/%E6%BA%90%E7%A0%81%E9%98%85%E8%AF%BB/</link>
    <description>Recent content in 源码阅读 on Hellokitty&#39;s Blog</description>
    <generator>Hugo</generator>
    <language>zh-CN</language>
    <lastBuildDate>Sun, 30 Aug 2026 23:09:10 +0800</lastBuildDate>
    <atom:link href="https://yangyang233333.github.io/categories/%E6%BA%90%E7%A0%81%E9%98%85%E8%AF%BB/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>SGLang 双 Stream 重叠调度：如何把 CPU 后处理藏到 GPU 计算背后</title>
      <link>https://yangyang233333.github.io/posts/sglang-overlap-scheduling/</link>
      <pubDate>Sun, 30 Aug 2026 23:09:10 +0800</pubDate>
      <guid>https://yangyang233333.github.io/posts/sglang-overlap-scheduling/</guid>
      <description>&lt;p&gt;大模型自回归推理看起来是纯 GPU 工作：每一步做一次模型前向，采样一个 token，再把 token 喂给下一步。然而在高性能推理系统里，GPU 计算只是流水线的一部分。采样结果回传、EOS 判断、请求回收、KV Cache 管理、下一批组装和元数据准备，都可能在两次前向之间制造空洞。&lt;/p&gt;
&lt;p&gt;SGLang 的 Overlap Scheduling 解决的正是这个问题。它不是简单地“多开一条 CUDA stream”，而是同时完成两件事：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;让当前步产生的 token 留在 GPU，直接作为下一步输入，解除下一次 forward 对 CPU 读值的依赖；&lt;/li&gt;
&lt;li&gt;用 scheduler stream 和 engine stream 构造软件流水线，让 GPU 计算当前批次时，调度器处理上一批次的结果。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;本文以 Mini-SGLang 的 &lt;code&gt;python/minisgl/scheduler/scheduler.py&lt;/code&gt; 为线索，解释 &lt;code&gt;overlap_loop&lt;/code&gt;、&lt;code&gt;_forward&lt;/code&gt; 和 &lt;code&gt;_process_last_data&lt;/code&gt; 背后的依赖重排。&lt;/p&gt;
&lt;h2 id=&#34;先看结论优化的不是提交速度而是依赖关系&#34;&gt;先看结论：优化的不是“提交速度”，而是依赖关系&lt;/h2&gt;
&lt;p&gt;CUDA kernel 的提交本来就是异步的。CPU 把工作放进 stream 后，不必等待 GPU 完成。因此一个自然的问题是：只用一条 stream，只要 CPU 提交得足够快，不也能让 GPU 连续工作吗？&lt;/p&gt;
&lt;p&gt;如果系统只有计算任务，这个判断基本成立。但自回归推理存在一个控制依赖：调度器通常要知道采样出的 token，才能判断请求是否命中 EOS、是否应该释放资源，以及下一轮有哪些请求仍应留在 batch 中。&lt;/p&gt;
&lt;p&gt;串行执行会形成如下链条：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;GPU:  forward(B1) ── idle ── forward(B2) ── idle ── forward(B3)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;CPU:               处理 B1                 处理 B2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   读 token                读 token
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   判 EOS                  判 EOS
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   组 B2                   组 B3
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;GPU 完成 &lt;code&gt;B1&lt;/code&gt; 后，CPU 才读取结果并决定 &lt;code&gt;B2&lt;/code&gt;。此时 GPU 没有可执行的新工作，只能等待。这不是 CPU 调用 CUDA API 太慢，而是 &lt;code&gt;B2&lt;/code&gt; 在逻辑上依赖 &lt;code&gt;B1&lt;/code&gt; 的结果。&lt;/p&gt;</description>
    </item>
    <item>
      <title>tiny-llm：在 Apple Silicon 上从 Transformer 算子走到推理系统与 Agent</title>
      <link>https://yangyang233333.github.io/posts/tiny-llm-source-reading/</link>
      <pubDate>Thu, 27 Aug 2026 15:10:20 +0800</pubDate>
      <guid>https://yangyang233333.github.io/posts/tiny-llm-source-reading/</guid>
      <description>&lt;p&gt;如果你已经知道 Transformer 的基本结构，却仍然不清楚 vLLM 一类推理系统为什么需要 KV Cache、Continuous Batching、Paged Attention，以及这些技术最终如何支撑 Agent，&lt;code&gt;skyzh/tiny-llm&lt;/code&gt; 是一条很好的动手路径。&lt;/p&gt;
&lt;p&gt;它不是一个追求生产可用的迷你框架，而是一门以 Qwen3 和 MLX 为载体的系统课程：先用可读的数组运算实现模型，再围绕真实性能瓶颈写 Metal 内核，随后搭出动态批处理和分页缓存，最后把同一个本地模型接入带工具、检查点、压缩、评测和分支选择的 Agent 循环。&lt;/p&gt;
&lt;p&gt;截至 2026 年 8 月 27 日，项目约有 4.5k stars，使用 Apache-2.0 许可证。课程主体分为四周，已覆盖从注意力到受控 Agent 的完整主线。&lt;/p&gt;
&lt;h2 id=&#34;项目定位不是再写一个-transformer&#34;&gt;项目定位：不是“再写一个 Transformer”&lt;/h2&gt;
&lt;p&gt;很多教学项目止步于“加载权重并生成一句话”。tiny-llm 的不同之处，是把模型实现当作起点，而不是终点。&lt;/p&gt;
&lt;p&gt;它试图回答三个递进的问题：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;一个现代开源模型如何由矩阵运算变成文本？&lt;/li&gt;
&lt;li&gt;一个正确但缓慢的实现，如何通过测量和内核优化接近成熟框架？&lt;/li&gt;
&lt;li&gt;一个推理引擎如何进一步成为可暂停、可审计、可恢复的 Agent 执行器？&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;项目选择 Apple Silicon、MLX 和 Qwen3。统一内存让 CPU、GPU 和模型权重处在相对简单的硬件环境里；MLX 提供熟悉的 Python 数组接口，同时允许下沉到 Metal；Qwen3 则带有 GQA、QK Norm、BF16 激活和 4-bit 权重，足以暴露真实推理系统中的带宽、注意力与缓存问题。&lt;/p&gt;
&lt;p&gt;代码结构刻意分成两套：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;src/tiny_llm/&lt;/code&gt; 是学习者逐步补全的实现；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;src/tiny_llm_ref/&lt;/code&gt; 是参考实现，用于测试和基准对照；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;src/extensions/&lt;/code&gt; 与 &lt;code&gt;src/extensions_ref/&lt;/code&gt; 分别放置 Metal/C++ 扩展；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tests_refsol/&lt;/code&gt; 按周和天组织验收测试；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;book/&lt;/code&gt; 是完整课程正文。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这种布局把“阅读—实现—测试—测量”闭成了环。&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
