CTranslate2 CPU上的批量翻译是否会导致不同的输出?

3gtaxfhh  于 3个月前  发布在  其他
关注(0)|答案(8)|浏览(44)

我有一个CPU模型,在不同的时间对相同的字符串产生不同的输出。
我认为这可能与#546中的bug有关,即GPU上的批量翻译产生了不同的结果。我目前使用的是CTranslate2 1.20.1版本,因此有很多更新我错过了。
或者,我记得在GPU上,批量翻译可能会产生略有不同的数值结果,并且我很好奇CPU模型和批量翻译是否也可能发生这种情况?

bxgwgixi

bxgwgixi1#

是的,相同的字符串在CPU上的批量翻译中可能会产生不同的输出。我知道这可能发生在Intel MKL(英特尔CPU上默认的后端)和oneDNN(AMD CPU上默认的后端)上。点积注意力的数值结果可能会因为输入中的填充位置数量而略有不同。
如果你正在运行在英特尔CPU上,可以通过启用strict numerical reproducibility来解决这个问题。尝试设置这个环境变量:

MKL_CBWR=AUTO,STRICT
vlf7wbxs

vlf7wbxs2#

我实际上使用AMD进行部署,这很不幸😔
如果我在AMD CPU上设置CT2_USE_MKL=1,CTranslate2会使用MKL吗?
对于CT2_USE_MKL=1MKL_CBWR=AUTO,STRICT,我猜测结果将是可重复的,但需要注意的是,由于MKL如何处理AMD CPU,它的速度会变慢。

lf3rwulv

lf3rwulv3#

如果我在AMD CPU上设置CT2_USE_MKL=1,CTranslate2会使用MKL吗?
是的。
我尝试在oneDNN中添加一个类似的标志,但他们不打算实现它。

iyfjxgzm

iyfjxgzm4#

我已经用AMD和Intel的CPU运行了几个测试,MKL_CBWR=AUTO,STRICT似乎不能与两者都兼容。我可以使用MKL_CBWR=COMPATIBLE从Intel和AMD获得可重复的输出,令人惊讶的是,使用这个标志的AMD CPU性能比Intel的好得多。
ctranslate2的轮子是基于MKL 2019 Update 3还是更早的版本构建的?鉴于MKL_CBWR=AUTO,STRICT似乎不起作用,我猜它们是针对早期MKL版本构建的,而MKL_CBWR=AUTO,STRICT标志是在那时引入的。
现在我看到轮子是基于非常近期的版本构建的。

ou6hu8tu

ou6hu8tu5#

根据英特尔文档,MKL_CBWR=COMPATIBLE确实是唯一支持非英特尔CPU的配置:
仅在非英特尔CPU上支持MKL_CBWR_COMPATIBLE选项。
这可以解释为什么MKL_CBWR=AUTO,STRICT不能在AMD上工作。然而,它应该在英特尔上按预期工作。你能检查一下在英特尔上的测试是否正确设置了吗?
ctranslate2的轮子是用MKL 2019 Update 3还是更早的版本构建的?
它们使用较新的MKL版本。例如,CTranslate2 1.20.1轮子已经开始使用英特尔MKL 2021.2。

ttisahbt

ttisahbt6#

这是在Intel CPU上设置MKL_VERBOSE=1后的输出,CNR被设置为AUTO,STRICT

MKL_VERBOSE SAXPBY(10,0x7ff56cb8eeb8,0x7ff56019f700,1,0x7ff56cb8eec0,0x7ff56019f700,1) 350ns CNR:AUTO,STRICT Dyn:1 FastMM:1 TID:0  NThr:4
MKL_VERBOSE ISAMAX(512,0x7ff56814c6c0,1) 276ns CNR:AUTO,STRICT Dyn:1 FastMM:1 TID:1  NThr:1
MKL_VERBOSE SGEMM(N,N,1,10,10,0x7ff56cb8ed38,0x7ff560005440,1,0x7ff54c013880,10,0x7ff56cb8ed40,0x7ff5600e91c0,1) 9.57us CNR:AUTO,STRICT Dyn:1 FastMM:1 TID:0  NThr:4
MKL_VERBOSE SAXPBY(10,0x7ff56cb8eeb8,0x7ff5600e91c0,1,0x7ff56cb8eec0,0x7ff5600e91c0,1) 194ns CNR:AUTO,STRICT Dyn:1 FastMM:1 TID:0  NThr:4
MKL_VERBOSE GEMM_S8U8S32(T,N,C,1536,20,512,0x7ff56d38f4c0,0x562f12bf7d40,512,0x7ff56d38f530,0x7ff5682860c0,512,0x7ff56d38f518,0x7ff56d38f4c8,0x7ff56818fd00,1536,0x562f14807000) 125.56us CNR:AUTO,STRICT Dyn:1 FastMM:1 TID:0  NThr:4
MKL_VERBOSE SGEMM_BATCH_STRIDED(T,N,2,1,64,0x7ff56d38f658,0x7ff56810f580,64,128,0x7ff5681edf00,64,64,0x7ff56d38f660,0x7ff568147ec0,2,2,160) 11.22us CNR:AUTO,STRICT Dyn:1 FastMM:1 TID:0  NThr:4
MKL_VERBOSE SGEMM_BATCH_STRIDED(N,N,64,1,2,0x7ff56d38f658,0x7ff56818fd00,64,128,0x7ff5681826c0,2,2,0x7ff56d38f660,0x7ff568147ec0,64,64,160) 12.36us CNR:AUTO,STRICT Dyn:1 FastMM:1 TID:0  NThr:4
MKL_VERBOSE SAXPBY(5120,0x7ff56cb8ec08,0x7ff5601c0300,1,0x7ff56cb8ec10,0x7ff5601c0300,1) 3.32us CNR:AUTO,STRICT Dyn:1 FastMM:1 TID:0  NThr:4
MKL_VERBOSE ISAMAX(512,0x7ff568160fc0,1) 328ns CNR:AUTO,STRICT Dyn:1 FastMM:1 TID:2  NThr:1

当它设置为Intel兼容时,输出是一致的,但速度显著降低。
在一个Intel doc中,我看到:
Intel和Intel兼容CPU有一些指令,如近似指令rcpps/rsqrtps,它们可能返回不同的结果。将分支设置为MKL_CBWR_COMPATIBLE
确保Intel® oneAPI Math Kernel Library
不使用这些指令,并强制执行仅包含Intel SSE2的单一代码路径。
这似乎表明,即使严格的CNR也不能保证一致的结果,只有兼容模式才能保证。

pkln4tw6

pkln4tw67#

感谢您的反馈。我还没有看到MKL_CBWR=AUTO,STRICT不足以在相同的CPU上获得相同输出的情况。不确定这是否重要,但您是在运行普通的还是相对的Transformer?
无论如何,保证一致的结果通常是很难的。最简单的方法是接受翻译可能存在细微的变化,但我知道向最终用户解释这一点是很困难的。
目前,我不了解是否有其他不会导致性能损失的解决方法,但我会继续探索。

n1bvdmb6

n1bvdmb68#

谢谢Guillaume。

这是一个非常小的子集,只有MKL_CBWR=AUTO,STRICT能够体验到这种现象,我们主要注意到它对于短数字字符串,如货币模式,但也有一些短语。

很难向最终用户解释这一点。

当然!我们最明显的问题是货币字符串,比如€18.10第一次翻译成法语可能是18,10 €,下一次可能是18h10

不确定这是否重要,但你是运行纯正则还是相对正则的Transformer吗?

它是纯正则的Transformer。

无论如何,保证一致的结果通常是很难的。

是的,我完全理解,修复这个问题并不容易。

我们已经切换到了同步翻译而不是批处理CPU,性能影响不大。所以,我很乐意坚持使用同步翻译。我们之前也为我们的GPU部署做了同样的事,一致的输出对我们来说更重要,所以如果它能保证结果,我们愿意进行同步翻译而不是批处理。

相关问题