【问题标题】:How computationally expensive is `exp`?`exp` 的计算成本有多高?
【发布时间】:2015-02-01 12:34:36
【问题描述】:

我目前正在听一场关于自动语音识别 (ASR) 的讲座。上一讲是关于向量量化(VQ)和k个最近邻(kNN)以及二叉树和高斯混合模型(GMM)。

据讲师介绍,VQ 用于通过计算 GMM 的近似值来加速 GMM 的评估。这是通过在 GMM 中找到具有最高值的高斯并向上查找该向量的值来完成的(来自先前构建的字典,存储为二叉树)。每个 GMM 大约有 42 个高斯。根据讲师的说法,这应该会加快计算速度,因为 e 函数(exp,自然指数函数)的计算成本很高。

我很好奇这是否(仍然)正确,搜索了 Python 实现并找到了 this answer,这说明 exp 是由硬件计算的。

如今的 CPU(和 GPU)很复杂,我对它们的了解非常有限。 exp 仍然可能比 e.g. 贵得多。浮点数、加法或乘法的比较。

问题

  • 与浮点比较、加法、乘法和类似的基本命令相比,exp 的成本如何?
  • 我是否最终理解了为什么在 ASR 中进行 VQ 有什么错误?

实验评估

我试图通过开始实验来获得结果。但是我很难消除数字错误造成的其他影响(例如缓存、变量查找时间、随机数生成器的时间……)。

目前,我有

#!/usr/bin/env python

import math
import time
import random

# Experiment settings
numbers = 5000000
seed = 0
repetitions = 10

# Experiment
random.seed(seed)
values = [random.uniform(-5, 5) for _ in range(numbers)]
v2 = [random.uniform(-5, 5) for _ in range(numbers)]

# Exp
for i in range(repetitions):
    t0 = time.time()
    ret = [math.exp(x) for x in values]
    t1 = time.time()
    time_delta = t1 - t0
    print("Exp time: %0.4fs (%0.4f per second)" % (time_delta, numbers/time_delta))

# Comparison
for i in range(repetitions):
    t0 = time.time()
    ret = [x+y for x, y in zip(values, v2)]
    t1 = time.time()
    time_delta = t1 - t0
    print("x+y time: %0.4fs (%0.4f per second)" % (time_delta, numbers/time_delta))

但我猜zip 让这个失败了,因为结果是:

Exp time: 1.3640s (3665573.5997 per second)
Exp time: 1.7404s (2872978.6149 per second)
Exp time: 1.5441s (3238178.6480 per second)
Exp time: 1.5161s (3297876.5227 per second)
Exp time: 1.9912s (2511009.5658 per second)
Exp time: 1.3086s (3820818.9478 per second)
Exp time: 1.4770s (3385254.5642 per second)
Exp time: 1.5179s (3294040.1828 per second)
Exp time: 1.3198s (3788392.1744 per second)
Exp time: 1.5752s (3174296.9903 per second)
x+y time: 9.1045s (549179.7651 per second)
x+y time: 2.2017s (2270981.5582 per second)
x+y time: 2.0781s (2406097.0233 per second)
x+y time: 2.1386s (2338005.6240 per second)
x+y time: 1.9963s (2504681.1570 per second)
x+y time: 2.1617s (2313042.3523 per second)
x+y time: 2.3166s (2158293.4313 per second)
x+y time: 2.2966s (2177155.9497 per second)
x+y time: 2.2939s (2179730.8867 per second)
x+y time: 2.3094s (2165055.9488 per second)

【问题讨论】:

  • 我不知道 GMM 或 VQ 的具体情况,但如果他/她让你检查一下,看起来你的讲师做得很好。无论如何,我发现例如在 CUDA 中,exp 是在 CUDA 数学工具库中实现的,而不是(直接)在硬件中实现的。此外,this 指出 Sandy Bridge CPU 也没有在硬件中实现 exp
  • 您的基准测试主要由 Python 解释器开销控制,+ 有 2 个操作数,但 exp 只有 1 个操作数。exp 明显慢于浮点 +。此外,不幸的是,您链接的 Martijn 的答案是关于 exp 直接在硬件中实现的错误;大多数 CPU ISA 并非如此。即使是旧版 x87(某些 32 位 x86 数学库可能使用也可能不使用)也只有微编码的 f2xm1,而不是任何真正的 x86 CPU 上的专用硬件。
  • 快速逼近exp 是非常可能的,不过,这要归功于基于mantissa * 2^exponent 的二进制浮点;您可以将 arg 的整数部分填充到浮点数(带有整数位移)的指数字段中,并对小数部分进行快速多项式逼近。特别是如果您不需要完整的float 精度,这可能非常快,就像三阶多项式非常好,只需要大约 3 个 FMA。

标签: gpu cpu speech-recognition computer-architecture exp


【解决方案1】:

据讲师介绍,VQ 用于通过计算 GMM 的近似值来加速 GMM 的评估。这是通过在 GMM 中找到具有最高值的高斯并向上查找该向量的值来完成的(来自先前构建的字典,存储为二叉树)。每个 GMM 大约有 42 个高斯。

这是一个正确的描述。您可以在以下论文中找到关于最优高斯计算的有趣描述:

George Saon、Daniel Povey 和 Geoffrey Zweig,“超快 LVCSR 解码器的剖析”,Interspeech 2005。 http://www.danielpovey.com/files/eurospeech05_george_decoder.pdf

似然计算部分

根据讲师的说法,这应该会加快计算速度,因为 e 函数(exp,自然指数函数)的计算成本很高。

在这部分你可能误解了讲师。 exp 不是一个非常重要的问题。由于其他原因,高斯计算很昂贵:每帧有几千个高斯得分,每帧有几十个分量,每个分量有 40 个浮点数。由于您需要提供和存储的内存量,处理所有这些数据的成本很高。高斯选择在这里有助于将高斯的数量减少几倍,从而加快计算速度。

使用 GPU 是解决此问题的另一种方法。通过将评分转移到 GPU,您可以显着加快评分。但是,HMM 搜索存在一个问题,即它不能轻松并行化。这是解码的另一个重要部分,即使您将评分降低到零,由于搜索,解码仍然会很慢。

Exp时间:1.5752s(每秒3174296.9903) x+y时间:9.1045s(每秒549179.7651)

这不是一个有意义的比较。您在这里忽略了许多事情,例如 Python zip 调用的成本(izip 更好)。这样您就可以轻松演示任何结果。

【讨论】:

    猜你喜欢
    • 2023-03-28
    • 2017-03-29
    • 1970-01-01
    • 2019-07-11
    • 2014-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多