<?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>Framework on CctoctoFX</title>
    <link>https://pillumina.github.io/tags/framework/</link>
    <description>Recent content in Framework on CctoctoFX</description>
    <image>
      <title>CctoctoFX</title>
      <url>https://pillumina.github.io/imgs/icon_head.png</url>
      <link>https://pillumina.github.io/imgs/icon_head.png</link>
    </image>
    <generator>Hugo -- 0.148.2</generator>
    <language>en</language>
    <lastBuildDate>Mon, 25 Aug 2025 11:30:12 +0800</lastBuildDate>
    <atom:link href="https://pillumina.github.io/tags/framework/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>[VeRL] DataProto介绍</title>
      <link>https://pillumina.github.io/posts/aiinfra/10-verl-dataproto/</link>
      <pubDate>Mon, 25 Aug 2025 11:30:12 +0800</pubDate>
      <guid>https://pillumina.github.io/posts/aiinfra/10-verl-dataproto/</guid>
      <description>&lt;h1 id=&#34;verl-dataproto-实现原理与数据流动分析&#34;&gt;Verl DataProto 实现原理与数据流动分析&lt;/h1&gt;
&lt;h2 id=&#34;目录&#34;&gt;目录&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://pillumina.github.io/posts/aiinfra/10-verl-dataproto/#1-%e6%a6%82%e8%bf%b0&#34;&gt;1. 概述&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pillumina.github.io/posts/aiinfra/10-verl-dataproto/#2-dataproto-%e6%a0%b8%e5%bf%83%e6%9e%b6%e6%9e%84&#34;&gt;2. DataProto 核心架构&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pillumina.github.io/posts/aiinfra/10-verl-dataproto/#3-hybridflow-%e8%ae%be%e8%ae%a1%e7%90%86%e5%bf%b5&#34;&gt;3. HybridFlow 设计理念&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pillumina.github.io/posts/aiinfra/10-verl-dataproto/#4-%e6%8e%a7%e5%88%b6%e6%b5%81%e4%b8%8e%e8%ae%a1%e7%ae%97%e6%b5%81%e5%88%86%e7%a6%bb&#34;&gt;4. 控制流与计算流分离&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pillumina.github.io/posts/aiinfra/10-verl-dataproto/#5-%e6%95%b0%e6%8d%ae%e6%b5%81%e5%8a%a8%e6%9c%ba%e5%88%b6&#34;&gt;5. 数据流动机制&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pillumina.github.io/posts/aiinfra/10-verl-dataproto/#6-dispatch-%e6%a8%a1%e5%bc%8f%e8%af%a6%e8%a7%a3&#34;&gt;6. Dispatch 模式详解&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pillumina.github.io/posts/aiinfra/10-verl-dataproto/#7-%e6%80%a7%e8%83%bd%e4%bc%98%e5%8c%96%e7%ad%96%e7%95%a5&#34;&gt;7. 性能优化策略&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pillumina.github.io/posts/aiinfra/10-verl-dataproto/#8-%e6%80%bb%e7%bb%93&#34;&gt;8. 总结&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;1-概述&#34;&gt;1. 概述&lt;/h2&gt;
&lt;p&gt;Verl 是一个基于 HybridFlow 论文的开源强化学习训练框架，专门为大语言模型的后训练优化而设计。其核心创新在于将控制流和计算流分离，通过 DataProto 协议实现高效的数据交换。&lt;/p&gt;
&lt;h2 id=&#34;2-dataproto-核心架构&#34;&gt;2. DataProto 核心架构&lt;/h2&gt;
&lt;h3 id=&#34;21-数据结构设计&#34;&gt;2.1 数据结构设计&lt;/h3&gt;
&lt;p&gt;DataProto 是 verl 框架中用于数据交换的核心协议，所有在 Worker 之间流转的数据，都被统一封装在一个名为 DataProto 的数据结构中。它不仅仅是一个字典，更承载着 RLHF 流程中所有的信息演变, 基于 PyTorch 的 TensorDict 构建：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@dataclass&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;DataProto&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;batch&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;TensorDict&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;              &lt;span class=&#34;c1&#34;&gt;# 张量数据容器&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;non_tensor_batch&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;dict&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;field&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;default_factory&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# 非张量数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;meta_info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;dict&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;field&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;default_factory&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;         &lt;span class=&#34;c1&#34;&gt;# 元信息&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;核心特性：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;统一接口&lt;/strong&gt;: 提供标准化的数据容器，支持张量和非张量数据&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;设备管理&lt;/strong&gt;: 自动处理 GPU/CPU 设备间的数据移动&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;内存优化&lt;/strong&gt;: 支持分块处理和内存复用&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;序列化&lt;/strong&gt;: 支持高效的序列化和反序列化&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;22-数据一致性检查&#34;&gt;2.2 数据一致性检查&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;check_consistency&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&amp;#34;检查 DataProto 的一致性&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;batch&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;batch&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;batch_size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;只支持 num_batch_dims=1&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;non_tensor_batch&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;val&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;non_tensor_batch&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;items&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;val&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ndarray&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# 检查批次大小一致性&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;batch&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;non_tensor_batch&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;batch_size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;batch&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;batch_size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;val&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;non_tensor_batch&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;items&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;val&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;shape&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;batch_size&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;3-hybridflow-设计理念&#34;&gt;3. HybridFlow 设计理念&lt;/h2&gt;
&lt;h3 id=&#34;31-设计动机&#34;&gt;3.1 设计动机&lt;/h3&gt;
&lt;p&gt;传统 RL 系统面临的问题：&lt;/p&gt;</description>
    </item>
    <item>
      <title>[VeRL] AgentLoop源码走读</title>
      <link>https://pillumina.github.io/posts/aiinfra/09-verl-agentloop/</link>
      <pubDate>Thu, 14 Aug 2025 11:30:12 +0800</pubDate>
      <guid>https://pillumina.github.io/posts/aiinfra/09-verl-agentloop/</guid>
      <description>&lt;p&gt;最近 RL sys 圈子的吴锡斌老师在 verl 上设计了将 rollout 与 tool 调用解耦的 AgentLoop，实现了自由灵活的 mutli-turn RL。在每个 AgentLoop 内部，rollout engine 只对外提供一个 token-in-token-out 的接口，而 tool 调用则通过 &lt;code&gt;ToolAgentLoop&lt;/code&gt; 来实现。我个人比较喜欢这样解耦的设计，同时，AgentLoop 的代码结构也比较清晰。我个人学习了一次整个代码后，觉着 AgentLoop 的设计甚是不错，但是 &lt;code&gt;ActorRolloutRefWorker&lt;/code&gt; 的历史包袱还是很重。&lt;/p&gt;
&lt;p&gt;本文简单分析了 agent loop 的源码，并给出了一些自己的看法。&lt;/p&gt;
&lt;p&gt;如果我们把整个 &lt;code&gt;ActorRolloutRefWorker&lt;/code&gt; 当做一个 &lt;code&gt;sgl.Engine&lt;/code&gt; 的话，AgentLoop 里面包装的两层 &lt;code&gt;AsyncSGLangServer&lt;/code&gt; 和 &lt;code&gt;AsyncLLMServerManager&lt;/code&gt;。&lt;code&gt;AsyncSGLangServer&lt;/code&gt; 相当于在 &lt;code&gt;sgl.Engine&lt;/code&gt; 上包装了 &lt;code&gt;fastapi&lt;/code&gt; 成了 server，而 &lt;code&gt;AsyncLLMServerManager&lt;/code&gt; 是在 server 上包了一层 router 做 load balance，相当于 sglang 的 router。这两层设计都是合理的，主要麻烦的是 &lt;code&gt;ActorRolloutRefWorker&lt;/code&gt;，层层调用，最后一共经过 7 个 class 才调到 &lt;code&gt;sgl.Engine&lt;/code&gt;，最近 verl 团队也在致力于对这块 worker class 的重构，敬请期待。最后，&lt;code&gt;AgentLoopManager&lt;/code&gt;，&lt;code&gt;AgentLoopWorker&lt;/code&gt; 和 &lt;code&gt;AgentLoop&lt;/code&gt; 这三层，我觉得 &lt;code&gt;AgentLoopWorker&lt;/code&gt; 可能未必有必要，其他两层挺合理的。&lt;/p&gt;</description>
    </item>
    <item>
      <title>[VeRL] 参数速览</title>
      <link>https://pillumina.github.io/posts/aiinfra/05-verl-params/</link>
      <pubDate>Thu, 14 Aug 2025 10:20:12 +0800</pubDate>
      <guid>https://pillumina.github.io/posts/aiinfra/05-verl-params/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;VeRL框架的参数众多，基于当前（2025.8.5）主线分支整理，附带了相关的理解，一些描述不一定完全正确，供学习参考。&lt;/p&gt;&lt;/blockquote&gt;
&lt;h2 id=&#34;batch-size&#34;&gt;Batch Size&lt;/h2&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;参数名称&lt;/th&gt;
          &lt;th&gt;详细解释&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;data.train_batch_size&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;作用&lt;/strong&gt;：定义了单次训练发送给 Rollout Engine 的样本数量，也即这是在每个 PPO 迭代开始时，从训练数据集中采样的提示 （Prompt）数量。&lt;br&gt;&lt;br&gt;&lt;strong&gt;详细解释&lt;/strong&gt;：这个值是 RL 训练中的基本样本数量。例如，设置为 1024 意味着在一次迭代中会：&lt;br&gt;1. 从数据集中随机抽取 1024 个 prompt。&lt;br&gt; 2. 将这 1024 个 prompt 发送给当前的 Rollout Engine 中，从而得到 1024 组完整的 trajectories（prompt, response）。&lt;br&gt;3. 接下来，这 1024 个 trajectories 进行经验计算（make experience），后续用于 Actor 和 Critic 模型的更新。&lt;br&gt;&lt;br&gt;&lt;strong&gt;影响与权衡&lt;/strong&gt;：影响总共训练的样本量。&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;data.val_batch_size&lt;/code&gt; （Deprecated)&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;作用&lt;/strong&gt;：在 Validation 阶段使用的批次大小。&lt;br&gt;&lt;br&gt;&lt;strong&gt;详细解释&lt;/strong&gt;：这与 &lt;code&gt;train_batch_size&lt;/code&gt; 类似，但仅用于评估模型性能，不参与训练。如果设置为 &lt;code&gt;null&lt;/code&gt;，会使用验证集的大小作为默认值。Note: 已经deprecated，推荐设置为 null。此时，整个 validation dataset 一次性发给 SGLang engines，自行进行内存管理。&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;actor_rollout_ref.actor.ppo_mini_batch_size&lt;/code&gt; &lt;br&gt; &lt;code&gt;critic.ppo_mini_batch_size&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;作用&lt;/strong&gt;：定义了 PPO 训练更新中的 mini-batch 大小。&lt;br&gt;&lt;br&gt;&lt;strong&gt;详细解释&lt;/strong&gt;：&lt;code&gt;data.train_batch_size&lt;/code&gt; 收集到的全部经验数据将被分割成多个 mini-batch，每块的大小就是 &lt;code&gt;ppo_mini_batch_size&lt;/code&gt;。模型每处理完一个 mini-batch，才会进行一次参数更新。&lt;br&gt;例如，如果 &lt;code&gt;train_batch_size = 1024&lt;/code&gt;，&lt;code&gt;ppo_mini_batch_size = 256&lt;/code&gt;，那么在一个 PPO Epoch 中，模型会进行 &lt;code&gt;1024 / 256 = 4&lt;/code&gt; 次参数更新。&lt;br&gt;&lt;br&gt;&lt;strong&gt;影响与权衡&lt;/strong&gt;：增大 mini-batch，单次更新的梯度更稳定，但更新频率更低，更新次数减少。&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;actor_rollout_ref.actor.ppo_micro_batch_size_per_gpu&lt;/code&gt; &lt;br&gt; &lt;code&gt;critic.ppo_micro_batch_size_per_gpu&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;作用&lt;/strong&gt;：定义了在单个 GPU 上进行一次 forward/backward 的数据大小。&lt;br&gt;&lt;br&gt;&lt;strong&gt;详细解释&lt;/strong&gt;：这是实现梯度累积的核心参数。mini-batch 会被再次切分为若干个 micro-batch。例如，在单卡上，&lt;code&gt;ppo_mini_batch_size = 256&lt;/code&gt;，&lt;code&gt;ppo_micro_batch_size_per_gpu = 32&lt;/code&gt;，那么梯度累积的步数就是 &lt;code&gt;256 / 32 = 8&lt;/code&gt;。这意味着模型会运行 8 次 forward 得到 loss，然后 backward 的到 gradient。每次处理 32 个样本，直到累积完整个 mini-batch 计算出的梯度。此时，使用累积的总梯度，对模型参数进行一次更新（&lt;code&gt;optimizer.step()&lt;/code&gt;）。这个值必须根据显存大小来严格调整，是防止 OOM 的关键。&lt;br&gt;&lt;br&gt;&lt;strong&gt;影响与权衡&lt;/strong&gt;：增大此值，减少了梯度累积的次数，可以提高训练的吞吐量，增大显存消耗。&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;actor_rollout_ref.actor.ppo_micro_batch_size&lt;/code&gt; &lt;br&gt; &lt;code&gt;critic.ppo_micro_batch_size&lt;/code&gt;（Deprecated)&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;作用&lt;/strong&gt;：已弃用，被 &lt;code&gt;per_gpu&lt;/code&gt; 版本取代，因为它能更好地适应分布式训练环境。&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;dynamic-batch-size&#34;&gt;Dynamic Batch Size&lt;/h2&gt;
&lt;p&gt;当样本长度差异很大时，按样本数量划分批次可能导致不同批次的计算量极不均衡，而基于 token 总数来控制 batch size 是一种平衡每个 batch 训练时间的方案。&lt;/p&gt;</description>
    </item>
    <item>
      <title>[RL4LLM] 异步RL框架: Slime</title>
      <link>https://pillumina.github.io/posts/aiinfra/02-slime/</link>
      <pubDate>Thu, 07 Aug 2025 17:10:12 +0800</pubDate>
      <guid>https://pillumina.github.io/posts/aiinfra/02-slime/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/THUDM/slime&#34;&gt;https://github.com/THUDM/slime&lt;/a&gt;&lt;br&gt;
一个异步实现但是非完全异步的RL框架&lt;/p&gt;&lt;/blockquote&gt;
&lt;h2 id=&#34;总体架构&#34;&gt;总体架构&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;从源码模块划分，有三大核心模块：
&lt;ul&gt;
&lt;li&gt;training（Megatron）：主训练流程，负责模型参数更新。&lt;/li&gt;
&lt;li&gt;rollout（SGLang + router）：负责采样、奖励/验证生成，产生训练数据。&lt;/li&gt;
&lt;li&gt;data buffer：桥接训练与采样，管理数据流、缓存与生成方式。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;分布式调度：关于资源分配、actor启动、任务调度都由于Ray管理，支持异步训练和采样&lt;/li&gt;
&lt;li&gt;插件机制：支持自定义buffer、模型、模型格式转换（mbridge）&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&#34;mermaid&#34;&gt;
  flowchart LR
    subgraph Ray[Ray 分布式调度]
        A1[Actor Group&amp;lt;br&amp;gt;训练 Actor]
        A2[Rollout Group&amp;lt;br&amp;gt;采样/生成 Actor]
        A3[Placement Group&amp;lt;br&amp;gt;资源分配]
    end
    subgraph Training[Training &amp;lt;Megatron&amp;gt;]
        T1[模型训练]
        T2[权重同步]
        T3[评估/保存]
    end
    subgraph Rollout[Rollout &amp;lt;SGLang+Router&amp;gt;]
        R1[采样/生成]
        R2[奖励模型]
        R3[过滤器]
    end
    subgraph Buffer[Data Buffer]
        B1[数据缓存]
        B2[数据流转]
        B3[Offload/Onload]
    end
    subgraph Plugins[插件机制]
        P1[Buffer 插件]
        P2[Model 插件]
        P3[mbridge 格式转换]
    end

    A1--&amp;gt;|训练数据|B1
    A2--&amp;gt;|生成数据|B1
    B1--&amp;gt;|数据流|A1
    B1--&amp;gt;|数据流|A2
    A1--&amp;gt;|权重同步|A2
    A1--&amp;gt;|评估/保存|T3
    A2--&amp;gt;|采样/奖励/过滤|R1
    R1--&amp;gt;|奖励|R2
    R1--&amp;gt;|过滤|R3
    B1--&amp;gt;|插件扩展|P1
    A1--&amp;gt;|模型扩展|P2
    A1--&amp;gt;|格式转换|P3
    A3--&amp;gt;|资源分配|A1
    A3--&amp;gt;|资源分配|A2
&lt;/pre&gt;

&lt;h2 id=&#34;各模块视角的关系图&#34;&gt;各模块视角的关系图&lt;/h2&gt;
&lt;h3 id=&#34;slimerollout-组件图&#34;&gt;slime/rollout 组件图&lt;/h3&gt;
&lt;p&gt;rollout 负责采样、奖励、过滤，支持多种采样/奖励/过滤策略。&lt;/p&gt;</description>
    </item>
    <item>
      <title>[RL4LLM] 异步RL框架: Areal</title>
      <link>https://pillumina.github.io/posts/aiinfra/03-areal/</link>
      <pubDate>Thu, 07 Aug 2025 14:40:12 +0800</pubDate>
      <guid>https://pillumina.github.io/posts/aiinfra/03-areal/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/inclusionAI/AReaL&#34;&gt;https://github.com/inclusionAI/AReaL&lt;/a&gt;&lt;br&gt;
纯异步RL方案&lt;/p&gt;&lt;/blockquote&gt;
&lt;h2 id=&#34;异步ppo训练调用流程&#34;&gt;异步PPO训练调用流程&lt;/h2&gt;
&lt;pre class=&#34;mermaid&#34;&gt;
  graph TD
    A[用户执行: examples/run_async_ppo.sh] --&amp;gt; B[training/main_async_ppo.py]
    B --&amp;gt; C[AsyncPPOMATHConfig配置解析]
    C --&amp;gt; D[training/utils.py: run_experiment]
    
    D --&amp;gt; E[Ray初始化]
    E --&amp;gt; F[exp_cfg.initial_setup]
    F --&amp;gt; G[AsyncRLExperimentConfig.initial_setup]
    G --&amp;gt; H[创建ExperimentConfig]
    
    H --&amp;gt; I[启动Workers]
    I --&amp;gt; J[MasterWorker]
    I --&amp;gt; K[ModelWorker]
    I --&amp;gt; L[GenerationServer]
    I --&amp;gt; M[GserverManager]
    I --&amp;gt; N[RolloutWorker]
    
    %% MasterWorker训练流程
    J --&amp;gt; J1[MasterWorker._poll_async]
    J1 --&amp;gt; J2[FunctionExecutor.execute_step]
    J2 --&amp;gt; J3[执行数据流图遍历]
    J3 --&amp;gt; J4[发送训练请求到ModelWorker]
    
    %% ModelWorker处理流程
    K --&amp;gt; K1[ModelWorker._poll]
    K1 --&amp;gt; K2[接收MasterWorker请求]
    K2 --&amp;gt; K3[处理训练/推理请求]
    K3 --&amp;gt; K4[执行模型前向/反向传播]
    
    %% Rollout流程
    N --&amp;gt; N1[RolloutWorker._poll_async]
    N1 --&amp;gt; N2[load_next_data]
    N2 --&amp;gt; N3[allocate_new_rollout]
    N3 --&amp;gt; N4[agent.collect_trajectory]
    N4 --&amp;gt; N5[env.step计算奖励]
    N5 --&amp;gt; N6[推送数据到训练端]
    
    %% 生成服务器流程
    L --&amp;gt; L1[GenerationServer._poll]
    L1 --&amp;gt; L2[启动SGLang子进程]
    L2 --&amp;gt; L3[处理生成请求]
    
    %% 生成服务器管理器
    M --&amp;gt; M1[GserverManager._poll]
    M1 --&amp;gt; M2[HTTP服务线程]
    M2 --&amp;gt; M3[请求调度和权重更新]
    
    %% 数据流
    N6 --&amp;gt; O[stream_dataset.py]
    O --&amp;gt; J4
    
    %% 异步通信
    J4 -.-&amp;gt;|异步请求| K2
    N3 -.-&amp;gt;|HTTP请求| M2
    M2 -.-&amp;gt;|调度请求| L3
    
    %% 权重更新
    K4 --&amp;gt; P[参数更新]
    P --&amp;gt; Q[权重同步]
    Q --&amp;gt; M3
    M3 --&amp;gt; R[更新生成服务器权重]
    
    style A fill:#e1f5fe
    style J fill:#f3e5f5
    style K fill:#e8f5e8
    style L fill:#fff3e0
    style M fill:#fce4ec
    style N fill:#f1f8e9
&lt;/pre&gt;

&lt;h3 id=&#34;用户入口到配置解析&#34;&gt;用户入口到配置解析&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;examples/run_async_ppo.sh&lt;/code&gt; → &lt;code&gt;training/main_async_ppo.py&lt;/code&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>[VeRL] Multi-Turn RL训练源码走读（2）</title>
      <link>https://pillumina.github.io/posts/aiinfra/08-verl-multiturn-2/</link>
      <pubDate>Sun, 03 Aug 2025 17:30:12 +0800</pubDate>
      <guid>https://pillumina.github.io/posts/aiinfra/08-verl-multiturn-2/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;在 Part 1 中，我们介绍了 verl 的初始化过程，我们进一步介绍 verl 的训练过程，包括rollout部分、make experience部分以及training部分。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;在 GRPO 中，单个 step 包含四个阶段：load data -&amp;gt; rollout -&amp;gt; make experience -&amp;gt; update model。区别于前一节的详述，本节会使用伪代码结合源码的方式进行阐述。&lt;/p&gt;
&lt;pre class=&#34;mermaid&#34;&gt;
  flowchart LR
subgraph W2[&amp;#34;Initialize&amp;#34;]
WP[Process Data] --&amp;gt; A
direction TB D1[Data Prepare] --&amp;gt; A
A[TaskRunner] --&amp;gt; B1[RayPPOTrainer]
B1 --&amp;gt; Workers

    subgraph Workers[&amp;#34;Workers&amp;#34;]
        direction TB
                WA[ActorRolloutWorker] --&amp;gt; WD[FSDP Engine]
        WB[CriticWorker] --&amp;gt; WD
        WC[RewardModelWorker] --&amp;gt; WD
        WD --&amp;gt; WE[SGLang Engine]
    end
    
    Workers --&amp;gt; C1[Hybrid Engine]
end 

subgraph W3[&amp;#34;Train Loop&amp;#34;]
    direction TB
    E[DataLoader] --&amp;gt; RolloutBox
    
    subgraph RolloutBox[&amp;#34;Rollout&amp;#34;]
        F1[Prepare Data] --&amp;gt; F2[SGLang Async Rollout]
        F2 --&amp;gt; F3[Multi-turn Chat Process]
    end
    
    RolloutBox --&amp;gt; ExpBox
    
    subgraph ExpBox[&amp;#34;Make Experience&amp;#34;]
        G1[Recompute Log Probs] --&amp;gt; G2[Compute Reward]
        G2 --&amp;gt; G3[Compute Advantage]
    end
    
    ExpBox --&amp;gt; UpdateBox
    
    subgraph UpdateBox[&amp;#34;Train The Model&amp;#34;]
        H1[Load FSDP Model Weight] --&amp;gt; H2[Compute Gradient]
        H2 --&amp;gt; H3[Weights Update]
        H3 --&amp;gt; H4[Sync Weights]
    end
    
    UpdateBox --&amp;gt; E
end

W2 --&amp;gt; W3
&lt;/pre&gt;

&lt;h2 id=&#34;数据加载与预处理&#34;&gt;数据加载与预处理&lt;/h2&gt;
&lt;p&gt;verl 通过 &lt;code&gt;DataProto&lt;/code&gt; 和 &lt;code&gt;RLHFDataset&lt;/code&gt; 来实现数据处理。具体来说，在 &lt;a href=&#34;https://github.com/volcengine/verl/blob/76f63cffa5081564d8fea93a1cb3ce8bd5bdcc39/verl/trainer/main_ppo.py#L193&#34;&gt;&lt;code&gt;main_ppo.py&lt;/code&gt;&lt;/a&gt; 中，我们观察这个函数：&lt;/p&gt;</description>
    </item>
    <item>
      <title>[VeRL] Multi-Turn RL训练源码走读（1）</title>
      <link>https://pillumina.github.io/posts/aiinfra/07-verl-multiturn-1/</link>
      <pubDate>Sun, 03 Aug 2025 15:30:12 +0800</pubDate>
      <guid>https://pillumina.github.io/posts/aiinfra/07-verl-multiturn-1/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;该part主要聚焦相关模块初始化部分&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;还是以 verl 出发，分析其 end to end mutli-turn RL 训练的全过程。整体上，我希望覆盖所有重要的 class 以及函数，更细粒度的代码不再展开。&lt;/p&gt;
&lt;p&gt;为了前后内容的一致性，基于 &lt;a href=&#34;https://github.com/volcengine/verl/commit/76f63cffa5081564d8fea93a1cb3ce8bd5bdcc39&#34;&gt;76f63cffa5&lt;/a&gt; 的 commit 进行分析。&lt;/p&gt;
&lt;p&gt;虽然本文以分析 verl 的代码为主，写完之后我才意识到，系统设计问题是非常通用的。诸如“log probs 重计算”，“Rollout Engine 显存管理”等等系统设计，是各大 RL 框架都需要考虑的核心问题。&lt;/p&gt;
&lt;p&gt;此外因为最近在学习SGLang的实现，本文的推理后端选择的是SGLang展开分析。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;整个训练的示意图如下，我们会具体展开每个部分。&lt;/p&gt;
&lt;pre class=&#34;mermaid&#34;&gt;
  flowchart LR
subgraph W2[&amp;#34;Initialize&amp;#34;]
WP[Process Data] --&amp;gt; A
direction TB D1[Data Prepare] --&amp;gt; A
A[TaskRunner] --&amp;gt; B1[RayPPOTrainer]
B1 --&amp;gt; Workers

    subgraph Workers[&amp;#34;Workers&amp;#34;]
        direction TB
                WA[ActorRolloutWorker] --&amp;gt; WD[FSDP Engine]
        WB[CriticWorker] --&amp;gt; WD
        WC[RewardModelWorker] --&amp;gt; WD
        WD --&amp;gt; WE[SGLang Engine]
    end
    
    Workers --&amp;gt; C1[Hybrid Engine]
end

subgraph W3[&amp;#34;Train Loop&amp;#34;]
    direction TB
    E[DataLoader] --&amp;gt; RolloutBox
    
    subgraph RolloutBox[&amp;#34;Rollout&amp;#34;]
        F1[Prepare Data] --&amp;gt; F2[SGLang Async Rollout]
        F2 --&amp;gt; F3[Multi-turn Chat Process]
    end
    
    RolloutBox --&amp;gt; ExpBox
    
    subgraph ExpBox[&amp;#34;Make Experience&amp;#34;]
        G1[Recompute Log Probs] --&amp;gt; G2[Compute Reward]
        G2 --&amp;gt; G3[Compute Advantage]
    end
    
    ExpBox --&amp;gt; UpdateBox
    
    subgraph UpdateBox[&amp;#34;Train The Model&amp;#34;]
        H1[Load FSDP Model Weight] --&amp;gt; H2[Compute Gradient]
        H2 --&amp;gt; H3[Weights Update]
        H3 --&amp;gt; H4[Sync Weights]
    end
    
    UpdateBox --&amp;gt; E
end

W2 --&amp;gt; W3
&lt;/pre&gt;

&lt;h2 id=&#34;数据预处理&#34;&gt;&lt;strong&gt;数据预处理&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;以 &lt;a href=&#34;https://huggingface.co/datasets/openai/gsm8k&#34;&gt;GSM8K&lt;/a&gt; 为例，预处理脚本是 &lt;code&gt;examples/data_preprocess/gsm8k_multiturn_w_tool.py&lt;/code&gt;。整个脚本只做了经典的 huggingface datasets mapping，核心逻辑如下：&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
