四、LDA优化

  1. 标准LDA 的模型训练过程中,对于文档 四、LDA优化 - 图1(令 四、LDA优化 - 图2,采用基于位置的更新) :

    四、LDA优化 - 图3

    常规的采样方式是:

    • 计算 四、LDA优化 - 图4
    • 将采样空间划分为:第一段 四、LDA优化 - 图5, 第二段 四、LDA优化 - 图6 ,… 第 四、LDA优化 - 图7四、LDA优化 - 图8 ,称作分桶。
    • 四、LDA优化 - 图9 之间均匀采样一个点,该点落在哪个桶内则返回对应桶的主题。
  2. 常规LDA 采样算法:

    • 四、LDA优化 - 图10 之间均匀采样一个点,假设为 四、LDA优化 - 图11 。其算法复杂度为 四、LDA优化 - 图12 ,因为需要计算 四、LDA优化 - 图13
    • 查找下标 四、LDA优化 - 图14 ,使得满足 四、LDA优化 - 图15 ,返回 四、LDA优化 - 图16 。通过二分查找,其算法复杂度为 四、LDA优化 - 图17
  3. 事实上如果执行非常多次采样,则常规LDA 采样算法第一步的成本可以分摊到每一次采样。因此整体算法复杂度可以下降到 四、LDA优化 - 图18 。如果仅执行一次采样,则整体算法复杂度为 四、LDA优化 - 图19

    四、LDA优化 - 图20四、LDA优化 - 图21 有关,而 四、LDA优化 - 图22 在文档 四、LDA优化 - 图23 的不同位置 四、LDA优化 - 图24 取值不同。这意味着每一次采样的概率分布都不同,因此采样每个主题的算法复杂度为 四、LDA优化 - 图25

  4. 有三种算法对采样过程进行了加速:

    • SparseLDAAliasLDA 使用基于位置的采样,这是为了方便对采样概率进行有效分解。
    • LightLDA 使用基于单词的采样,这种采样更能够满足LDA 的假设:LDA 假设同一篇文档中同一个单词都由同一个主题生成。

4.1 SparseLDA

  1. sparseLDA 推断比传统 LDA 快大约20倍,且内存消耗更少。

    四、LDA优化 - 图26

4.1.1 概率分解

  1. SparseLDA 主要利用了LDA 的稀疏性。事实上,真实场景下的一篇文档只会包含少数若干个主题,一个词也是参与到少数几个主题中。因此可以将采样公式分解(令 四、LDA优化 - 图27,采用基于位置的更新):

    四、LDA优化 - 图28

    令:

    四、LDA优化 - 图29

    其中:四、LDA优化 - 图30 仅仅和主题的单词统计有关;四、LDA优化 - 图31 和文档 四、LDA优化 - 图32 的主题统计、主题的单词统计都有关;四、LDA优化 - 图33 和文档 四、LDA优化 - 图34 的主题统计、主题的单词统计、文档 四、LDA优化 - 图35 的单词统计都有关。

    假设 四、LDA优化 - 图36 为常数,即:主题的所有单词的先验频数都为常数 四、LDA优化 - 图37 。现在仅考虑一篇文档的训练,因此忽略角标 四、LDA优化 - 图38 ,有:

    四、LDA优化 - 图39

  2. 四、LDA优化 - 图40 ,原始LDA 的采样方式为:

    • 四、LDA优化 - 图41 划分为 四、LDA优化 - 图42 个桶,将每个桶根据其 四、LDA优化 - 图43 分解继续划分为三个子桶。
    • 根据从均匀分布 四、LDA优化 - 图44 中采样一个点。该点落在那个桶,则采样该桶对应的主题。

    假设该点落在桶 四、LDA优化 - 图45 ,则有三种情况:

    • 若该点落在 r 对应的子桶,其概率为 四、LDA优化 - 图46
    • 若该点落在 s 对应的子桶,其概率为 四、LDA优化 - 图47
    • 若该点落在 q 对应的子桶,其概率为 四、LDA优化 - 图48
  3. 考虑重新组织分桶,按照 四、LDA优化 - 图49 划分为 [0,R)、[R,R+S)、[R+S,U) 三个桶。将第一个桶根据 四、LDA优化 - 图50 划分为 T 个子桶; 将第二个桶根据 四、LDA优化 - 图51 划分为 T 个子桶;将第三个桶根据 四、LDA优化 - 图52 划分为 T 个子桶。

    则上述采样过程的三种情况等价于:从均匀分布 四、LDA优化 - 图53 中采样一个点。该点落在那个桶,则就在桶内的子桶中继续采样主题。

    • 该桶落在 R 桶的子桶 t ,其概率为: 四、LDA优化 - 图54
    • 该桶落在 S 桶的子桶 t ,其概率为: 四、LDA优化 - 图55
    • 该桶落在 Q 桶的子桶 t ,其概率为: 四、LDA优化 - 图56四、LDA优化 - 图57

4.1.2 采样过程

  1. sparseLDA 采样过程中假设:在同一篇文档的同一次迭代期间,文档-主题 计数、主题-单词 矩阵保持不变。即:参数延迟更新。

  2. sparseLDA 采样过程:从均匀分布 四、LDA优化 - 图58 中采样一个点 四、LDA优化 - 图59

    • 如果 四、LDA优化 - 图60,则从 四、LDA优化 - 图61 中继续均匀采样一个点,设该点落在子桶 四、LDA优化 - 图62 ,则返回主题 四、LDA优化 - 图63

      考虑到 四、LDA优化 - 图64 对于同一篇文档中的所有位置都相同,这使得对桶 四、LDA优化 - 图65 采样的平摊算法复杂度为 四、LDA优化 - 图66

    • 如果 四、LDA优化 - 图67,则从 四、LDA优化 - 图68 中继续均匀采样一个点,设该点落在子桶 四、LDA优化 - 图69 ,则返回主题 四、LDA优化 - 图70

      此时只需要考虑当前文档中出现的主题,因为对于其它未出现的主题有 四、LDA优化 - 图71 ,则 四、LDA优化 - 图72

      因此对桶 四、LDA优化 - 图73 采样的算法复杂度为 四、LDA优化 - 图74四、LDA优化 - 图75 为文档中出现的主题数量。 同时内存消耗更少,因为只需要保存非零值对应的分量。

    • 如果 四、LDA优化 - 图76,则从 四、LDA优化 - 图77 中继续均匀采样一个点,设该点落在子桶 四、LDA优化 - 图78 ,则返回主题 四、LDA优化 - 图79

      此时只需要考虑使得当前单词 四、LDA优化 - 图80主题-单词 计数非零的那些主题。因为对于其它主题有 四、LDA优化 - 图81 ,则 四、LDA优化 - 图82

      因此对桶 四、LDA优化 - 图83 采样的算法复杂度为 四、LDA优化 - 图84四、LDA优化 - 图85 为当前单词 四、LDA优化 - 图86 涉及到的主题数量 。 同时内存消耗更少,因为只需要保存非零值对应的分量。

    • 整体推断的算法复杂度为 四、LDA优化 - 图87

  3. 对于小数据集,四、LDA优化 - 图88 ,但是对于大数据集可能发生 四、LDA优化 - 图89 。即:单词 四、LDA优化 - 图90 出现在了几乎所有主题中。

    假设单词 四、LDA优化 - 图91 由主题 四、LDA优化 - 图92 生成的可能性为 四、LDA优化 - 图93,则 四、LDA优化 - 图94 篇文档中 四、LDA优化 - 图95 至少由主题 四、LDA优化 - 图96 生成的一次的概率为:

    四、LDA优化 - 图97

    因此对于非常大的数据集对于 sparseLDA 是不利的。

4.2 AliasLDA

4.2.1 概率分解

  1. AliasLDA 通过引入 Alias TableMetropolis-Hastings 方法来进一步加快采样速度。

  2. AliasLDA 对采样公式进行不同的分解(令 四、LDA优化 - 图98,采用基于位置的更新):

    四、LDA优化 - 图99

    其中 四、LDA优化 - 图100 与文档无关。

  3. AliasLDA 采样过程是:从均匀分布 四、LDA优化 - 图101 中采样一个点 四、LDA优化 - 图102

    • 如果 四、LDA优化 - 图103,则从 四、LDA优化 - 图104 中继续均匀采样一个点,设该点落在子桶 四、LDA优化 - 图105 ,则返回主题 四、LDA优化 - 图106

      此时只需要考虑当前文档中出现的主题,因为对于其它未出现的主题有 四、LDA优化 - 图107 ,则 四、LDA优化 - 图108

      因此对桶 四、LDA优化 - 图109 采样的算法复杂度为 四、LDA优化 - 图110四、LDA优化 - 图111 为文档中出现的主题数量。 同时内存消耗更少,因为只需要保存非零值对应的分量。

    • 如果 四、LDA优化 - 图112,则从 四、LDA优化 - 图113 中继续均匀采样一个点,设该点落在子桶 四、LDA优化 - 图114 ,则返回主题 四、LDA优化 - 图115

      如果能够使得该子采样的算法复杂度为 四、LDA优化 - 图116,则整体采样的算法复杂度为 四、LDA优化 - 图117,要大大优于 sparseLDA四、LDA优化 - 图118

4.2.2 Alias Table

  1. Alias Table 用于将离散的、非均匀分布转换成离散的、均匀的分布。这是为了采样方便:离散均匀分布的采样时间复杂度为 四、LDA优化 - 图119

  2. 假设一个离散、非均匀分布为 四、LDA优化 - 图120

    常规的采样方式为:

    • 分桶:1:[0,1/2), 2:[1/2,5/6), 3:[5/6,11/12), 4:[11/12,1)
    • 采样:从0~1 之间均匀生成一个随机数 xx 落在哪个桶(二分查找),则返回对应的桶的编号。

    其平均每次采样的复杂度为 四、LDA优化 - 图121,其中 四、LDA优化 - 图122 为事件的数量。

  3. 一个改进的方法是:

    • 建立四个分桶,桶的编号分别为 1~4

    • 1~4 中均匀采样一个整数,决定落在哪个桶。假设在第 四、LDA优化 - 图123 个桶。

    • 0~1 之间均匀采样一个小数 四、LDA优化 - 图124,则:

      • 计算非归一化概率:四、LDA优化 - 图125 (即:归一化概率除以其中的最大值)。
      • 四、LDA优化 - 图126,则接受采样,返回事件 四、LDA优化 - 图127 ;若 四、LDA优化 - 图128,则拒绝接受,重新采样(重新选择分桶、重新采样小数)。

    理想情况下其算法复杂度为 四、LDA优化 - 图129,平均情况下算法复杂度为 四、LDA优化 - 图130

    可以看到:事件 四、LDA优化 - 图131 被选中的概率(非归一化)为:四、LDA优化 - 图132,归一化之后就是 四、LDA优化 - 图133

    四、LDA优化 - 图134

  4. Alias Table 在上述思想指导下更进一步,它对概率除以均值而不是最大值。

    • 构建 Alias Table (算法复杂度 四、LDA优化 - 图135):

      • 初始化数组 四、LDA优化 - 图136 ,第 四、LDA优化 - 图137 个桶的容量 四、LDA优化 - 图138 表示事件 四、LDA优化 - 图139 发生的概率;四、LDA优化 - 图140四、LDA优化 - 图141 存放第 四、LDA优化 - 图142 个桶中的另外一个事件的编号。

        四、LDA优化 - 图143 个桶要么完全由事件 四、LDA优化 - 图144 组成,要么由事件 四、LDA优化 - 图145 和另外一个事件组成(由 四、LDA优化 - 图146 给出)。每个桶最多包含2个事件。

      • 将每个桶的容量乘以 四、LDA优化 - 图147四、LDA优化 - 图148 。即:计算非归一化概率。

      • 构建队列 A,存放容量大于1的桶编号;构建队列 B,存放容量小于1的桶编号。

      • 处理每个桶,直到满足条件:队列 B 为空。处理方式为:

        从队列 A 取出一个桶,假设为 四、LDA优化 - 图149;从队列 B 取出一个桶,假设为 四、LDA优化 - 图150 。将 四、LDA优化 - 图151 填充到容量为1,填充的容量从 四、LDA优化 - 图152 消减。假设消减的容量为 四、LDA优化 - 图153

        • 记录容量:四、LDA优化 - 图154 ;登记: 四、LDA优化 - 图155

        注意:此时不需要更新 四、LDA优化 - 图156四、LDA优化 - 图157 存放的是事件 四、LDA优化 - 图158 的非归一化概率,也等于它在桶中的比例。

        • 四、LDA优化 - 图159 ,则继续放入队列A;若 四、LDA优化 - 图160,则放入队列B ;若 四、LDA优化 - 图161 ,则桶 四、LDA优化 - 图162 处理完成。

        最终每个桶的容量都是1,桶内最多存放两个事件(由 四、LDA优化 - 图163 记录)。

    • 1~N 中均匀采样一个整数,决定落在哪个桶。

    • 0~1 之间均匀采样一个小数 四、LDA优化 - 图164。假设在第 四、LDA优化 - 图165 个桶:若 四、LDA优化 - 图166 ,则返回事件 四、LDA优化 - 图167 ;否则返回事件 四、LDA优化 - 图168

四、LDA优化 - 图169

  1. Alias Table 的算法复杂度:

    • 构建 Alias Table 步骤复杂度 四、LDA优化 - 图170 ,采样步骤复杂度 四、LDA优化 - 图171
    • 如果采样1次,则算法复杂度为 四、LDA优化 - 图172 。如果采样非常多次,则构建 Alias Table 的代价会被平均,整体的平摊复杂度为 四、LDA优化 - 图173

4.2.3 MH 采样算法

  1. 如果直接对 四、LDA优化 - 图174 采用 Alias Table 采样,则会发现一个严重的问题:对于文档中不同位置 四、LDA优化 - 图175 的单词 四、LDA优化 - 图176 不同,因此概率分布 四、LDA优化 - 图177 随位置 四、LDA优化 - 图178 发生变化。这就相当于采样 1 次的 Alias Table 算法,完全没有发挥出 Alias Table 的优势。

    解决方式是:提出一个不随位置 四、LDA优化 - 图179 变化的概率分布 四、LDA优化 - 图180 ,它近似原始分布 四、LDA优化 - 图181 但是更容易采样。然后采用基于 MHMCMC 采样算法。

  2. 标准的 MH 算法需要构建状态转移矩阵,但是这里的状态转移比较特殊:状态转移概率仅与最终状态有关,与前一个状态无关,即: 四、LDA优化 - 图182

    • 算法输入: 近似概率分布 四、LDA优化 - 图183 ,原始概率分布 四、LDA优化 - 图184

    • 算法输出:满足原始分布的采样序列 四、LDA优化 - 图185

    • 算法步骤:

      • 从概率分布 四、LDA优化 - 图186 中随机采样一个样本 四、LDA优化 - 图187

      • 四、LDA优化 - 图188 执行迭代。迭代步骤如下:

        • 根据 四、LDA优化 - 图189 采样出候选样本 四、LDA优化 - 图190

        • 计算接受率 四、LDA优化 - 图191

          四、LDA优化 - 图192

        • 根据均匀分布从 四、LDA优化 - 图193 内采样出阈值 四、LDA优化 - 图194,如果 四、LDA优化 - 图195 ,则接受 四、LDA优化 - 图196, 即 四、LDA优化 - 图197 。否则拒绝 四、LDA优化 - 图198 , 即 四、LDA优化 - 图199

          由于 四、LDA优化 - 图200 近似于 四、LDA优化 - 图201,因此大多数情况下会接受 四、LDA优化 - 图202

      • 返回采样序列 四、LDA优化 - 图203

      注意:返回的序列中,只有充分大的 四、LDA优化 - 图204 之后的序列 四、LDA优化 - 图205 才是服从原始分布的采样序列。

4.2.4 AliasLDA

  1. AliasLDA 综合采用了 AliasTableMH 采样算法。对分桶 四、LDA优化 - 图206 采样的算法步骤:

    • 构建不随文档中的位置 四、LDA优化 - 图207 变化的概率分布 四、LDA优化 - 图208 ,算法复杂度 四、LDA优化 - 图209

    • 根据 四、LDA优化 - 图210 构建 AliasTable ,算法复杂度 四、LDA优化 - 图211

    • 循环:遍历文档的所有位置 四、LDA优化 - 图212

      对于文档的当前位置 四、LDA优化 - 图213 根据前述的 MH 算法采样出主题 四、LDA优化 - 图214 ,其算法复杂度为 四、LDA优化 - 图215

    考虑到前面两步的代价可以平摊到每次采样过程,因此平摊算法复杂度为 四、LDA优化 - 图216

4.3 LightLDA

  1. web-scale 规模的预料库非常庞大也非常复杂,通常需要高容量的主题模型(百万主题、百万词汇表,即:万亿参数级别)来捕捉长尾语义信息。否则,当主题太少时会丢失这些长尾语义信息。

    这种规模数据集的训练需要上千台机器的集群,而LightLDA 允许少量的机器来训练一个超大规模的LDA 主题模型,它可以用 8 台机器训练一个包含百万主题&百万词汇表(万亿级参数)、包含千亿级单词的数据集。

  2. LightLDA 主要采用了以下方法:

    • 更高效的MH 采样算法,其算法复杂度为 四、LDA优化 - 图217 ,并且与当前最先进的Gibbs 采样器相比收敛效率快了近一个量级。
    • structure-aware 的模型并行方案,其利用主题模型中的依赖关系,产生一个节省机器内存和网络通信的采样策略。
    • 用混合数据结构来存储模型,其针对高频单词和低频单词采用不同的数据结构,从而使得内存可以放置更大规模的模型,同时保持高效的推断速度。
    • 有界异步数据并行方案,其可以降低网络同步和通信的成本,从而允许通过参数服务器对海量数据进行有效的分布式处理。

4.3.1 structure-aware 模型并行

  1. 数据并行:分割数据集,将不同文档集交给不同的 worker 来处理。所有 worker 共享同一份模型参数,即:共享同一份全局 主题-单词 矩阵 四、LDA优化 - 图218

    如:YahooLDA 和 基于参数服务器的LDA 实现就是采取数据并行。

  2. 数据并行+模型并行:分割数据集,将不同文档集交给不同的 worker 来处理。同时分割模型,不同 worker 处理不同的 主题-单词 分布。即:每个worker 只会看到并处理本地文档出现过的单词的 主题-单词 分布。

    如:PLDAPeacock ,以及 LDA 就是采取这种策略。

  3. 为了解决模型内存需求太大与worker 内存较小的问题,LightLDA 提出了 structure-aware 模型并行方案。

    • 在每个worker 中,采样算法执行之前先将本 worker 分割到的数据集进一步划分为数据块 Data Block 1,Data Block 2,... 。同时计算每个数据块包含的单词的词汇表,并将该词汇表作为元数据附加到数据块上。

      该操作只需要线性扫描,其计算复杂度为 四、LDA优化 - 图219

    • workerData Block i 执行采样时:

      • 首先加载数据块 Data Block iworker 的内存,取得该 block 的元数据。

      • 然后根据元数据,将该数据块的词汇表划分为集合 四、LDA优化 - 图220

      • 对每个词表集合 四、LDA优化 - 图221 ,拉取参数服务器中的全局 主题-单词 矩阵 四、LDA优化 - 图222 中涉及 四、LDA优化 - 图223 的单词的部分,称作模型切片,记作 四、LDA优化 - 图224 。因此worker 仅仅需要保存模型的一个切片。

        然后对 Data Block i 中的所有文档执行采样并更新 四、LDA优化 - 图225 ,采样时仅仅考虑出现在 四、LDA优化 - 图226 中的单词。

      • 当对 四、LDA优化 - 图227 更新完毕时,将本次更新同步到参数服务器中的全局 主题-单词 矩阵 四、LDA优化 - 图228 。然后继续处理下一个词汇集合 四、LDA优化 - 图229

    • 一旦对 Data Block i 处理完毕,继续采样下一个数据块 Data Block i+1

    如下图所示为 Data Block 2 的采样过程,四、LDA优化 - 图230 表示该数据块包含的文档数量。在d1,d2,... 中的箭头给出了主题采样的顺序。每个文档通过灰色块表明出现对应的单词(出现一次或多次)、白色块表明没有出现对应的单词。

    四、LDA优化 - 图231

  4. structure-aware 除了降低worker 内存需求之外,还通过以下方式减轻网络通信瓶颈:

    • 在处理数据块 Data Block i 时,只有当前模型切片相关的所有单词都被采样时,才会移动到下一个模型切片。

      这使得在处理数据块 Data Block i 时,每个模型切片只需要被换入换出内存一次,而不是反复换入换出内存。模型切片的换入换出需要和参数服务器进行同步,因此多次交换会增大通信压力。

    • 在利用当前模型切片对数据块采样时,可以同步进行下一个模型切片的加载(从参数服务器拉取到本地)、上一个模型切片的同步更新(从本地推送到参数服务器)。

      这进一步降低了网络通信的时间延迟。

4.3.2 高效的 MH 采样算法

  1. AliasLDA 采样的计算复杂度为 四、LDA优化 - 图232 ,因此它不擅长处理比较长的文档,比如网页。这是因为:在初始迭代中,文档每个位置的主题都是随机初始化的,因此对于较长的文档 四、LDA优化 - 图233 非常大。这会使得AliasLDA 在迭代初期非常缓慢,消耗大量时间。

  2. 当利用分布 四、LDA优化 - 图234四、LDA优化 - 图235 进行采样时,一个好的 四、LDA优化 - 图236 需要满足两个条件(从而加速采样速度):从 四、LDA优化 - 图237 中采样相对更加容易;马尔科夫链更快混合mix

    因此在设计分布 四、LDA优化 - 图238 时,存在一个折中:

    • 如果分布 四、LDA优化 - 图239四、LDA优化 - 图240 更接近,则马尔科夫链混合的更快,但是从 四、LDA优化 - 图241 采样的代价可能与 四、LDA优化 - 图242 相差无几。
    • 如果分布 四、LDA优化 - 图243 非常容易采样但是与 四、LDA优化 - 图244 很不一样,则马尔科夫链混合的很慢。
  3. 所谓马尔科夫链的良好的混合意味着:马尔科夫链能够收敛,且收敛速度不会太长。

    当拒绝率太高时,MCMC 采样很可能长期处于某些值附近(如下图所示的平摊区域),搜索整个参数空间要花非常多的时间。下图中,横轴为迭代次数,纵轴表示采样结果。

    四、LDA优化 - 图245

  4. AliasLDASparseLDA 不同,LightLDA 用两个近似分布 四、LDA优化 - 图246 来对 四、LDA优化 - 图247 进行采样。

    考虑采样概率:

    四、LDA优化 - 图248

    • 定义 :

      四、LDA优化 - 图249

      其中 四、LDA优化 - 图250 为文档内主题 四、LDA优化 - 图251 的频次, 四、LDA优化 - 图252 为文档长度。则接受率为:

      四、LDA优化 - 图253

    • 定义:

      四、LDA优化 - 图254

      其中 四、LDA优化 - 图255 表示数据集 四、LDA优化 - 图256 中由主题 四、LDA优化 - 图257 生成的单词中单词 四、LDA优化 - 图258 的次数,四、LDA优化 - 图259 表示数据集 四、LDA优化 - 图260 中由主题 四、LDA优化 - 图261 生成的单词总频数。则接受率为:

      四、LDA优化 - 图262

  5. 为了提高对 四、LDA优化 - 图263 的采样效率,对 四、LDA优化 - 图264 进一步拆分:

    四、LDA优化 - 图265

    因此采样步骤为:

    • 首先从均匀分布 四、LDA优化 - 图266 中采样一个点。

    • 如果该点落在 四、LDA优化 - 图267 之间,则使用 四、LDA优化 - 图268 进行采样。此时无需建立 AliasTable,直接从文档中均匀随机选择一个单词,其背后的主题就是采样得到的主题,该分布刚好就是 四、LDA优化 - 图269

    • 如果该点落在 四、LDA优化 - 图270 之间,则使用 四、LDA优化 - 图271 进行采样。

      • 如果 四、LDA优化 - 图272 为常数,则此时 四、LDA优化 - 图273 为均匀分布,无需建立 AliasTable
      • 如果 四、LDA优化 - 图274 并不是全部相等,则由于 四、LDA优化 - 图275 与单词、文档都无关,因此可以建立全局 四、LDA优化 - 图276 AliasTable,它可以跨单词、跨数据块共享,其平均时间、空间复杂度为 四、LDA优化 - 图277

    因此从 四、LDA优化 - 图278 采样的平摊时间、空间复杂度均为 四、LDA优化 - 图279

  6. 为了提高对 四、LDA优化 - 图280 的采样效率,采用类似于 AliasLDAAlias Table 方式,从而使得对 四、LDA优化 - 图281 的采样复杂度为 四、LDA优化 - 图282

    • 注意:虽然在文档内部,四、LDA优化 - 图283 在不同位置处不同,是变化的,因此不满足 Alias Table 的要求。但是在同一个数据块中,对于同一个单词 四、LDA优化 - 图284四、LDA优化 - 图285 是相同的,是不变的,因此满足 Alias Table 的要求。因此 四、LDA优化 - 图286 是在同一个数据块内,跨文档共享。

    • 建立 四、LDA优化 - 图287 的空间复杂度是 四、LDA优化 - 图288 ,因为它需要存储 四、LDA优化 - 图289 个分桶的边界,以及桶内的值。为了降低空间复杂度,可以进一步拆分:

      四、LDA优化 - 图290

      其采样步骤为:

      • 首先从均匀分布 四、LDA优化 - 图291 中采样一个点。
      • 如果该点落在 四、LDA优化 - 图292 之间,则使用 四、LDA优化 - 图293 进行采样。此时只需要考虑单词 四、LDA优化 - 图294 涉及的主题即可,空间复杂度为 四、LDA优化 - 图295
      • 如果该点落在 四、LDA优化 - 图296 之间,则使用 四、LDA优化 - 图297 进行采样。它与单词 四、LDA优化 - 图298 无关,因此可以在所有单词之间共享,这使得平均的空间复杂度为 四、LDA优化 - 图299

      因此对 四、LDA优化 - 图300 的采样的平摊时间复杂度为 四、LDA优化 - 图301,平摊空间复杂度为 四、LDA优化 - 图302

  7. 考虑到 四、LDA优化 - 图303四、LDA优化 - 图304文档-主题 概率,与四、LDA优化 - 图305 比较接近; 四、LDA优化 - 图306主题-单词 概率,与四、LDA优化 - 图307 比较接近。

    • 如果仅仅用四、LDA优化 - 图308 采样,则有可能出现 四、LDA优化 - 图309 较小、 四、LDA优化 - 图310 很大的情形。此时 四、LDA优化 - 图311 较大,而 四、LDA优化 - 图312 较小,使得接受率较低,收敛速度较慢。
    • 同理:如果仅仅用四、LDA优化 - 图313 采样,则有可能出现 四、LDA优化 - 图314 较小、 四、LDA优化 - 图315 很大的情形。此时 四、LDA优化 - 图316 较大,而 四、LDA优化 - 图317 较小,使得接受率较低,收敛速度较慢。

    因此:虽然单独利用 四、LDA优化 - 图318 或者单独利用 四、LDA优化 - 图319 都可以对 四、LDA优化 - 图320 进行采样,但是单独使用时收敛速度较慢。

  8. LightLDA 联合采用 四、LDA优化 - 图321 来加速采样的收敛速度,它轮流在二者之间采样。这等价于用 四、LDA优化 - 图322 进行采样,其接受率较大、收敛速度较快。

    • 算法输入:原始函数分布 四、LDA优化 - 图323文档-主题近似分布四、LDA优化 - 图324主题-单词近似分布 四、LDA优化 - 图325

    • 算法输出:满足原始分布的采样序列 四、LDA优化 - 图326

    • 算法步骤:

      • 四、LDA优化 - 图327 中随机采样一个样本 四、LDA优化 - 图328

      • 四、LDA优化 - 图329 执行迭代。迭代步骤如下:

        • 根据 四、LDA优化 - 图330 采样出候选样本 四、LDA优化 - 图331 ,计算接受率 四、LDA优化 - 图332

          四、LDA优化 - 图333

          根据均匀分布从 四、LDA优化 - 图334 内采样出阈值 四、LDA优化 - 图335,如果 四、LDA优化 - 图336 ,则接受 四、LDA优化 - 图337, 即 四、LDA优化 - 图338 。否则拒绝 四、LDA优化 - 图339 , 即 四、LDA优化 - 图340

        • 根据 四、LDA优化 - 图341 采样出候选样本 四、LDA优化 - 图342 ,计算接受率 四、LDA优化 - 图343

          四、LDA优化 - 图344

          根据均匀分布从 四、LDA优化 - 图345 内采样出阈值 四、LDA优化 - 图346,如果 四、LDA优化 - 图347 ,则接受 四、LDA优化 - 图348, 即 四、LDA优化 - 图349 。否则拒绝 四、LDA优化 - 图350 , 即 四、LDA优化 - 图351

      • 返回采样序列 四、LDA优化 - 图352

4.3.3 混合数据结构

  1. 对于百万词汇表 x 百万主题,如果每一项(单词-主题计数)是 32 bit,则需要 4 TB内存才能存放。假设一台机器有 128 G内存,则至少需要 32 台参数服务器。因此如果能够大幅降低内存,则对硬件资源的需求也能够下降。

  2. 考虑词频统计,在数十亿网页文件中:

    • 在删除停用词之后,几乎所有单词的词频不超过 32 位无符号整数的上限。因此主题-单词 矩阵的元素采用 32 位无符号整数存放。
    • 大多数单词出现的次数少于 四、LDA优化 - 图353 次,四、LDA优化 - 图354 为主题数量(论文中为一百万)。这意味着主题-单词 矩阵中,大多数单词列是稀疏的,如果采用稀疏表示( 如hash 映射) 将显著减少内存需求。
  3. 采用稀疏表示存在一个问题:其随机访问性能很差,这会损害MCMC 采样的速度。为了保持高采样性能、低内存需求,LightLDA 提出了混合数据结构:

    • 对于词频较高的单词,其对应的主题计数列是不做修改的、方便随机访问的 dense 表示。这部分单词占据词表的 10% ,几乎覆盖了语料库中 95% 的位置。
    • 对于词频较低的长尾单词,其对应的主题计数列经过 hash 映射的 sparse 表示,使得内存需求大幅降低。这部分单词占据词表的 90%,仅仅覆盖了语料库中 5% 的位置。

    这就使得:

    • MCMC 采样中,对大多数主题-单词 列的访问都是 dense 表示,这使得采样的吞吐量很高。
    • 在存储方面,大多数主题-单词列的存储是sparse 表示,这使得内存需求较低。

4.3.4 系统实现

  1. LightLDA 使用开源的分布式机器学习系统 Petuum 来实现,特别使用其参数服务器来进行有界异步数据并行。

  2. 参数服务器用于存放 LDA 的两类模型参数:主题-单词 矩阵 四、LDA优化 - 图355 ,主题频次向量四、LDA优化 - 图356 ,其中 四、LDA优化 - 图357 为主题 四、LDA优化 - 图358 生成的单词的总数(它也等于 四、LDA优化 - 图359四、LDA优化 - 图360 行的求和)。

  3. 因为语料库的规模远大于模型的大小,所以在网络中交换文档的代价对网络压力非常大。因此LightLDA 并不是交换数据,而是交换模型:先将语料库随机分配到各个worker 的磁盘上,然后在整个算法期间每个 worker 仅仅访问本地磁盘上的部分语料库。

    交换数据的做法是:每轮迭代时,将语料库分发到不同 worker,每个 worker 在不同迭代步处理的数据会有所不同。

  4. LightLDA 整体架构如下图所示:

    • 各参数的意义位(这里采用论文中的符号表示):

      • 四、LDA优化 - 图361 :文档 四、LDA优化 - 图362 的长度;四、LDA优化 - 图363 :数据分片中包含的文档数量。四、LDA优化 - 图364 :文档 四、LDA优化 - 图365 的第 四、LDA优化 - 图366 个词汇的主题。
      • 四、LDA优化 - 图367 :语料库中主题 四、LDA优化 - 图368 生成的单词 四、LDA优化 - 图369 的数量,即 四、LDA优化 - 图370四、LDA优化 - 图371 :语料库中主题 四、LDA优化 - 图372 的频次,即 四、LDA优化 - 图373四、LDA优化 - 图374 行的求和。四、LDA优化 - 图375:文档 四、LDA优化 - 图376 的主题 四、LDA优化 - 图377 的频次。
      • 四、LDA优化 - 图378 :数据分片。 四、LDA优化 - 图379 :模型分片。四、LDA优化 - 图380 :主题频次向量。
    • 数据分片从 worker 的磁盘加载到 worker 的内存,模型分片由 worker 从参数服务器进行获取。

    • 考虑到每个数据分片可能仍然非常巨大,无法一次性加载进worker 内存。因此 LightLDA 将每个数据分片继续划分成数据块 Data Block ,并将这些数据块依次加载进内存处理。

    四、LDA优化 - 图381

  5. 为了加速并行处理,LightLDA 进行了如下优化:

    • 通过流水线来消除IO的延迟:在采样的同时可以加载数据块、拉取下一个模型分片、更新上一个模型分片。

      这需要根据采样器的吞吐量、数据块大小、模型切片大小仔细安排参数。

    • 为防止模型切片之间的数据不均衡(热门词和冷门词),需要对词汇表按照词频进行排序,然后对单词进行混洗来生成模型切片。

    • 在生成数据块时,将文档中的单词按照它们在词表中的顺序进行排序,从而确保同一个模型切片的所有单词在数据块中是连续的。这个操作只需要执行一次,与 LDA 整体消耗时间相比该操作非常快。

    • 使用有界异步数据并行来消除在相邻迭代边界处发生的网络等待时间。

  6. LightLDA 在每个 worker 内部开启多线程来进一步加速算法:

    • 每个数据块在内存中被划分为不相交的区域,每个区域由不同的线程进行采样。
    • 所有线程之间共享模型切片,且采样期间模型切片不变。在将模型切片更新到参数服务器之前,对各线程的更新结果进行聚合。

    通过保持模型切片不变,这避免了竞争条件和加锁/解锁等并发问题。虽然这种延迟更新方式需要更多的迭代步才能收敛,但是由于这种方式消除了并发问题,提高了采样器吞吐率,使得每个迭代步的速度快得多,因此整体上仍然可以加速收敛速度。