《Dynamic TCP Initial Windows and Congestion Control Schemes Through Reinforcement Learning 》论文阅读
1.problem
这篇论文主要聚焦两个问题:
TCP cannot deal with short flows gracefully
使用百度进行搜索时,请求发送的数据量很小。但在TCP拥塞控制算法里,由于初始的CWND 总是固定大小(IW, 2, 4, or 10),所以即便数据量很小,但可能也大于 CWND的尺寸,因而不得不需要几个RTT的时间;再者,在会话结束时,还是处于慢启动阶段,无法充分利用有效带宽。譬如上图,a1中,IW设置为1,而请求的size 为 3,需要 2 个 RTT;而在 a2 中,IW设置为3,只需要 1 个 RTT, 当然这一切建立在 The link supports CWND >= 3。在b中,由于 the link only supports CWND <= 2,所以设置 IW=3,会导致拥塞。
直观能想到的是,能够将固定大小的 CWND 改为自适应大小,不同的请求有对应最优的CWND尺寸, 像这种 short flows 能够一个RTT就能完成。
The performance of congestion control (CC) algorithms remains far from ideal
现今,有许多拥塞控制算法被提出,BBR、PCC Vivac、Copa等,这些算法都是在某个网络条件下性能很好,在其他条件下,性能差异很大。而实际的网路环境是随时间和空间变化的,如果只是静态地使用一种特定的 CC 算法,那么TCP的性能可能不理想。
因此同样的,能够动态地根据不同地网络环境,选择最优地 CC 算法,性能可能大有改观。
2. Solution
为了解决上述问题,作者使用 RL方法 根据 网络状态 动态配置 IW(initial window) 和 CC算法。即在 state(网络状态) 和 action(IW, CC) 建立映射,最大化期望奖励。
同样也面临着几个挑战:
How to measure the fresh TCP data on the server side only ?
RL 需要网络的指标(RTT, Throughput...)来表征网络条件状况,但是在web服务器上,如何不需要客户端合作就能单方面测量到这些指标。
论文中,作者修改了 Linux kernel和 Nginx software,使得 web 服务器无需客户协助即可实时收集和存储 TCP flow 性能指标。
How to apply RL methods on highly variable and non-continuous network conditions of Internet ?
由于不同客户端所处的用户粒度(IP、子网、地点)不同,导致网络条件的差异很大,因此需要合适 RL 方法,在不同的用户粒度能够使用不同的合适的CC方案。
论文中,作者提出一种 bottom-up 方法能够对具有相同网络特性的用户进行分组,以便找到最细粒度的用户组。然后,作者提出了 TCP-RL 算法,使用 深度 RL 为 per-flow level 针对不同的网络条件动态配置正确的已有的 CC 方案,而不是去构建新的 CC 方案。
How to rapidly search for the optimal TCP IW or CC from a large decision space?‘
由于 IW 和 CC 的 search 空间很大,需要一些巧妙地机制,能够快速收敛到最佳地 IW 和 CC。否则,如果做出决策的时间较长,会导致在这期间,网络条件已经发生了变化。
论文中,作者提出一种 滑动决策空间 (sliding-decision-space )方法能够快速收敛到最佳IW。针对CC,作者通过离线训练的神经网络模型可以直接在线选择合适的CC,不需要进行暴力(brute-force)搜索。
3.Background
本文主要使用了两个算法,一个是关于解决 the multi-armed bandit problem 的 UCB 算法;另外一个是 RL 中的 A3C (Asynchronous advantage actor-critic) 算法.
Upper Confidence Bound Algorithm
这是基于平稳的多臂赌博机问题的算法,可以参考该大佬的 blog 通俗易懂。
Asynchronous Advantage Actor-critic Algorithm
A2C (Advantage Actor-critic Algorithm)算法主要是通过 policy gradient 推导而来。
根据RL 最大化期望奖励,可列出期望的原始式,在这个式子中,\(R\left( \tau \right)\)是 agent与Env 实际交互的一条的trajectory的总奖励(由Env 所决定),\(P_{\varTheta}\left( \tau \right)\)则是这一条 trajectory 发生的概率。将 \(P_{\varTheta}\left( \tau \right)\) 展开,\(p_{\theta}\left( a_t|s_t \right)\) 根据当前状态 选择某个行为的概率,即是 agent 与 Env 交互的并且需要不断更新的 policy,而 \(p\left( s_{t+1}|s_t,a_t \right)\) 根据当前的 状态 和 行为 跳转到 下一个状态的概率, 是由 Env 决定的。
综上,能够发现,其实我们只需要针对 \(p_{\theta}\left( a_t|s_t \right)\) ,其它的可以从Env中获取,都可以理解为一常量,因此只需找到最佳的 \(\theta\) 使得 奖励的期望最大。
对 \(\overline{R_{\theta}}\) 进行求导化简即可,最终化简为针对 某个 trajectory 中 某个 experience 的形式 即可。针对最简式,运用梯度上升算法即可。
这个最简式也存在若干问题。
直观反应,如果选择该行为所对应的\(R\left( \tau ^n \right)\) 为正,我们就增加该行为\(p_{\theta}\left( a_{t}^{n}|s_{t}^{n} \right)\)的概率,反之,如果为负,则减少该行为\(p_{\theta}\left( a_{t}^{n}|s_{t}^{n} \right)\)的概率。
\[\nabla \overline{R_{\theta}}=\frac{1}{N}\sum_{n=1}^N{\sum_{t=1}^{T_n}{T\left( \tau ^n \right) \nabla \log p_{\theta}\left( a_{t}^{n}|s_{t}^{n} \right)}} \]Tip 1: Add a Baseline
问题:在许多游戏里,奖励总是正的,但是奖励的大小不同,最低为0。所以无论如何,都会增加该奖励对应行为的概率。如果现在有三个行为(a/b/c),目前agent 只是 sample 到 a 和 b 行为,由于所有动作的奖励都是正的,所以如果 c 行为一直没有sample 到,那么a 和 b行为的概率就是一直增加,由于 a b c的概率之和为1,因此,c 行为的概率会越来越低。但 c 行为不一定就是一个不好的行为,只是没有sample到。
解决:增加一个baseline,使得奖励有正有负,把那些奖励低于 baseline 的变为负值。
Tip 2: Assign Suitable Credit
问题:我们能够发现tip 1中公式,只要在同一个回合(episode)里面 ,所有的状态和动作的对都会使用同样的奖励 \(R\left( \tau ^n \right) - b\) 。很明显,这样很不公平,因为即便在同一个回合中,动作也有好有坏。
解决:因此,应该给每一个不同的动作乘上不同的权重,才能反应不同动作的好坏。
原本的权重是整个回合的奖励的总和,现在改成从某个时间 t 开始,假设这个动作是在 t 时刻执行的,从 t 这个时间点一直到游戏结束所有奖励的总和,才能代表这个动作的好坏。
更进一步,增加一个 discount factor -- \(\gamma \in \left[ 0,1 \right]\)。
原因:因为在 t 时刻执行某一个动作,会影响到后续的所有结果,可以理解为接下来的得到的奖励,都是由于 t 时刻的 动作决策所导致的。但结合实际,时间越长,这个影响力会越小,可能在时间点100 后的奖励只有 t 时刻行为决策的很微弱的影响。
- \(\gamma = 0\) : 只关心即时奖励,即 t 时刻获得奖励
- \(\gamma = 1\) : 未来奖励等同于即时奖励
我们把 R - b 这一项成为 优势函数,用 A来代表优势函数,该函数取决于 s 和 a,它的作用就是 critic ,用于去评判 某一个状态s 下 采取 a行为,有多好。
当然,我们最终需要推导到 A2C 形式中。
Advantage Actor-critic Algorithm
\(\sum_{t'=t}^{T_n}{\gamma ^{t'-t}r_{t'}^{n}-b}=G_{t}^{n}\ \Longrightarrow \ E\left[ G_{t}^{n} \right] =Q^{\pi _{\theta}}\left( s_{t}^{n},a_{t}^{n} \right)\) 。原本的 \(G_{t}^{n}\) 是实际采样值,但我们每次在同样 state 下 采用 同样的 action 得到的 reward 是不同的,因为 Env 使用的是一个 reward 的分布,但 实际sample 的次数有限,所以如果两次 sample 的 reward 值有很大的差别,就会使得训练过程不稳定,同样也无法反应出 reward 分布。因此采用 \(G_{t}^{n}\) 的期望,根据定义,\(G_{t}^{n}\) 的期望就是 \(Q^{\pi _{\theta}}\left( s_{t}^{n},a_{t}^{n} \right)\)。
\(b\Rightarrow V^{\pi _{\theta}}\left( s_{t}^{n} \right)\) 。我们依旧要保证前面 tips 的特性不丢失,优势函数依旧需要有正有负,因此将 b 改为状态价值函数,因为 \(V^{\pi _{\theta}}\left( s_{t}^{n} \right) =E\left[ Q^{\pi _{\theta}}\left( s_{t}^{n},a_{t}^{n} \right) \right]\) ,所以能够保证有正有负。
\(Q^{\pi _{\theta}}\left( s_{t}^{n},a_{t}^{n} \right) \Rightarrow r_{t}^{n}+V^{\pi}\left( s_{t+1}^{n} \right)\)。基于前两点改进去训练,我们需要估计2个网络:Q-network 和 V-network,所以估算的风险就变成两倍,所以我们希望只需要估测一个网络。根据 DQN 的 TD 思想,因此进行了如下变换。
A2C流程图
A3C
A3C 这个方法就是同时开很多个 worker, 那每一个其实就是一个分身。最后这些分身会把所有的经验,通通集合在一起。
TCP-RL
TCP-RL 总体的思想如上图所示。首先我们需要按照合适的细粒度对用户分组(user group1,user group2,user group3...)。server 类似于 Brain/agent,server 定时收集不同用户组的实时 performance measurement ,这些数据为RL中的state 和 reward,server根据这些数据进行计算,为不同的用户组找到下一步骤合适的 parm(IW or CC)。
User Grouping
如果为每个用户去训练学习得到合适的IW/CC,会出现一种窘境,就是每个用户没有足够的样本能够学习到合适的IW/CC。因此,作者考虑将用户按照不同的细粒度进行分组是一个好的方案。但也有几个挑战:
- too fine-grained user group。使得每个组缺少的样本数据进行训练学习。
- too coarse-grained user group。由于用户组分组过于粗糙,虽然样本足够,但训练结果无法最优。
基于以上挑战,作者提出了 bottom-up(finest-to-coarsest) searching technique 以便找到最优的用户分组。
作者以 (subnet,ISP,Province,All)这样一个细到粗的四个特征进行分组。
同时,作者以上式为标准衡量该分组是否成立。\(s\) 为时间步,\(X_s\) 为该组在时间步 s 的 reward,J 为 抖动(jitter)。通过该式去计算在一段时间 n 下,该组的reward抖动情况,由于reward 与 网络指标相关(throughput,RTT,loss rate...),因此也能反应网络的抖动情况。
分组条件:如果该组的抖动 \(J<T\) 阈值,则该组能够分组。
- step1,每一个节点代表一个分组,不同层即按照不同的细粒度分组,比如叶子节点是按照 all->province->ISP->subnet 分组的,蓝色节点为不满足分组条件,绿色节点满足分组。
- step2,将底部叶子节点中不满足条件的蓝色节点以 同兄弟节点 合并为一组 others 的节点,然后再次进行分组条件判定。譬如,S2自成一组 Others ,S4和S5合为一组 Others ,S7和S8合并为一组 Others,然后再次判定这三组是否符合分组条件,能够发现 Others(S4+S5)满足条件变为绿色。
- step3,将不满足条件的 others 组(主要需要同祖父母节点,即同 beijing 节点)再次合并为更大的 others 节点,并且上调与父节点(ISP level)成为兄弟节点,再次进行分组条件判定。依旧不合格。
- step4,同理再次上调到更高一层进行分组条件判断,直到成为根节点的子节点。如果依旧不合格,该蓝色 other 节点按照标准的IW进行配置,而绿色节点使用 RL 进行配置。
RL For IW Configuration
作者将 IW 学习作为 RL 中 非平稳多臂赌博机问题(non-stationary multi-armed bandit problem)。non-stationary 即赌博机 Reward 的分布随时间变化,但不会变化太大。这是一个经典的问题,因此作者使用了 discount UCB algorithm。
\[\overline{X_t}\left( \gamma ,i \right) +c_t\left( \gamma ,i \right) \]上式为该算法的核心公式,我们需要对每个 arm 计算该公式,找到最大的值(最大置信区间上界),即下一次就选择该值对应的 arm。
\(\overline{X_t}\left( \gamma ,i \right)\) 是对第 \(i\) 个 arm 已经 discount 的平均 reward 值。其中 \(N_t\left( \gamma ,i \right)\) 为第 \(i\) 个 arm被选中的次数,\(X_s(i)\) 为第 \(i\) 个 arm 在第 s 次的即时奖励,\(\gamma\) 为 discount factor,总共在所有的 arm(1,2,3......) 中选择了 t 次,\(I_s = i\) 即 第 \(s\) 次选择的 arm 刚好为 第 \(i\) 个 arm ,则为1, 否则为0。
\(c_t\left( \gamma ,i \right)\) 为 discounted padding function,它用来控制置信区间的宽度,其中 \(B\) 为常数,\(\xi>0\) 。当某个 arm 经常被选择,那么 \(c_t\left( \gamma ,i \right)\) 就会越来越小,同样置信区间宽度会越来越窄,\(\overline{X_t}\left( \gamma ,i \right)\) 也会越来越趋向于实际期望值。
- step_1,将 \(K\) 个 arm 都执行一遍,并做好标记(\(I_t = t\))
- step_2,从 \(K+1\) 到 \(T\) ,每一次迭代,我们先找到 arm 中最大的 \(\overline{X_t}\left( \gamma ,i \right) +c_t\left( \gamma ,i \right)\) 值,然后选择该最大值对应的 arm。
Reward Function Definition — \(X_s(i)\)
这个奖励函数的定义基于 最大化吞吐量,最小化时延 的想法设计。如果只是单方面最大化 吞吐量不考虑时延,是导致 缓冲队列 也会填满,时延增加,最后导致 buffer bloat 从而拥塞丢包;同样如果只是考虑 最小化时延,会 永远以 低速率 传输数据,无法全部利用带宽,造成带宽浪费。因为两者结合才能达到 时延带宽积。
\(Throughput_s(i)\) 为第 \(i\) 个IW在 \(s\) 时刻的吞吐量 ,\(RTT_s(i)\) 为第 \(i\) 个 IW 在 \(s\) 时刻的 \(RTT\) ,\(Throughput_{\max}\) 和 \(RTT_{\min}\) 为过去时间内的最大吞吐量和最小往返时延。\(\alpha\) 是对 \(Throughput\) 和 \(RTT\) 的占比衡量,如果 \(\alpha\) 越小,则 \(RTT\) 的权重增加,反之,\(Throughput\) 权重增加。
\(X_s(i)\) 的被 normalized 到 \([0,1]\) 中。
Arms Definition
IW 有一个连续的并且很大的 value space,我们需要从中找到最优的 IW。如果使用对整个空间蛮力搜索,效率会很低。因此,作者提出来 sliding-decision-space method。
- step_1,我们为每一个 Arm 设定一个滑动窗口,滑动窗口大小为4.(前提:search space 是有序的)。
- step_2,我们使用 discount UCB 算法找出该窗口内的最佳 IW 的值。
- step_3,如果该窗口内 最佳IW 值是该滑动窗口内最小或最大的IW值之一,对应着滑动窗口向前或向后滑动一格,查看更小或更大的IW值是否更优,直至找到最优的滑动停止;如果该窗口内最大IW值和最小IW值都不是最佳 IW 值,那么不需要滑动,直接找到了全局最优(窗口中间值)。
因此,解决 short flow 问题,总的思路,先要根据用户的网络特征进行分组,然后以 group 为单位,服务器端为每个 user group 使用 discount UCB 算法找到最佳的 IW 大小。
RL For CC Configuration
由于每个 user group 的网络特征不同,因此需要为不同的 user group 配置选择最优的 CC 算法(大约14种 CC 方案)。作者使用了 A3C 算法。
如Fig.5 所示,刚开始,每个 user group 都有一个 initial CC schema,而后服务器端会去收集 每个的性能指标数据(throughput、RTT、Loss Rate...)作为 state,然后把 state 输入到 agent 模型中,得到该状态的value function 和 policy (每个 CC 方案的概率大小),选择最大概率的CC方案作为该 user group 的 CC 方案即可。
- State,\(S_t=(Throughput,RTT_t,Loss_t)\) 作为 agent 输入。
- Policy,它是 action(CC)的概率分布,能够得到每个 action 的概率大小,和为1(Softmax)。
- Reward,采取某个 action 后 Network Env 所反馈的回报(将性能指标数据转换为 reward \(r_t=\log \left( \frac{Throughput_t}{RTT_t} \right)\) 最大化吞吐量,最小化时延)。
由于网络环境变化频繁,复杂,仅通过 current state ,RL 模型可能难以观察到网络环境的变化,因此,作者离线训练了一个神经网络来监测网络环境的变化。以上一步的 state 和 action 以及 current state 作为输入,输出环境是否改变的概率。用以配合 RL 。
System Design
- Request,user 发送 request 请求到 Frontend Server 建立连接。
- Look up && output(CC/IW),Connection Manager 根据该 User IP 到 IW Table 进行查表,找到合适的IW;将 User state 输入到离线的 Neural Network 模型中得到合适的 CC 方案。
- Response,Connection Manager 将 IW 和 CC 响应给 User。
- Performance data,User 根据 IW 和 CC 进行数据传输到 Fronted Server,Data Collector 收集 User 的实时性能数据。
- Fresh data,Data Collector 将 Performance data 预处理变为 Fresh data。
- Update,Reinforcement Learning(discount UCB、A3C) 根据 Fresh data 进行训练,并且将output(IW and parameter)传输到 Fronted Server,对 IW Table 和 Neural Network 进行update。
- 后面回到第一步开始,user 再次获得 IW or CC。
Conclusion
作者提出的 TCP_RL 算法主要是为了解决两个问题:short flow 的 IW 配置问题,long flow 的 CC 配置问题。TCP_RL 中的 discount UCB 是为每个 user group 找到合适的 IW,A3C 是为每个 User group 找到合适的 CC。因为网络环境的多变性,而目前无论 CC 或 IW 都是 静态配置的无法达到很好的性能,因此 需要动态配置 CC 或 IW。