Overview
先上结论,是两个数据对象分别在GPU和CPU的原因。
- indices is a tensor shaped (1,token_size) in GPU
- interactionset is a set in CPU
当我遍历indices 查看item是否在interactionset 里时,出现了非常慢的现象。
step1 分析原因
token_size 大概是6000+,众所周知,find in set的复杂度大概为O(1) or O(log),虽然python常数比 较大,但是理论上最慢也会在1s内处理完下面一条语句。
pred_item_sample = [int(indices[-1][j]) for j in range(len(indices[-1])) if int(indices[-1][j]) in interactionset]
step2 猜测是不是常数太大的问题
然后我又测试对indices自身进行topk,sort操作,不改变shape的情况下,运行时间远远<1s。
排除python常数的问题。
step3 tensor or numpy ?
从 tensor 转成 numpy ,需要先传到cpu,然后速度变得非常快,但是分析之后其实不是数据格式的原因。
indices = indices.to('cpu').numpy()
step4 CPU or GPU ?
由于楼主是调包新手,对于tensor和其他基本类型的存储位置不敏感,之前只是model 跑不起来才会去改:比如step3里提到的tensor传到cpu再转numpy。
回头看step 1 ,每次从GPU 里拿一条tensor,在CPU的set上做find,一共拿6w+次,直观上这个代价是很大的。但是如果一开始都把tensor放到cpu上,这个代价上我不知道怎么算,也不知道torch 底层是怎么做的,但是直觉上会大大减少CPU和GPU的交互次数,因此降低很大的计算代价。
如果之后有看到这部分实现或者分析,再续上(挖坑。