我在一个AI项目中使用Redis。
我们的想法是让多个环境模拟器在多个CPU内核上运行策略。模拟器将经验(状态/动作/奖励元组的列表)写入redis服务器(重放缓冲区)。然后训练进程将经验作为数据集读取以生成新策略。新策略部署到模拟器,删除以前运行的数据,然后进程继续。
大部分的体验都是在“状态”中捕获的。状态通常表示为一个大的numpy数组,比如80 x 80。模拟器在cpu允许的情况下尽可能快地生成这些。
为此,有没有人有好的想法或经验的最好/最快/最简单的方法来编写大量的numpy数组到redis。这是所有在同一台机器上,但后来,可以在一组云服务器上。代码样本欢迎!
6条答案
按热度按时间bqjvbblv1#
我不知道它是不是最快,但你可以试试这样的...
将Numpy数组存储到Redis是这样的-参见函数
toRedis()
:检索Numpy数组是这样的-请参阅函数
fromRedis()
:字符串
您可以通过将Numpy数组的
dtype
与形状沿着编码来增加更多灵活性。我没有这样做,因为可能您已经知道所有数组都是一种特定类型,然后代码会变得更大,更难阅读。现代iMac上的粗略基准:
型
Keywords:Python,Numpy,Redis,array,serialize,serialize,key,incr,unique
mwngjboj2#
你也可以考虑使用msgpack-numpy,它提供了“编码和解码例程,可以使用高效的msgpack格式对numpy提供的数值和数组数据类型进行序列化和非序列化”--参见https://msgpack.org/。
快速概念验证:
字符串
在我的机器上,msgpack运行速度比使用struct快得多:
型
g6baxovj3#
下面我重写了函数
fromRedis
和toRedis
来处理可变维大小的数组,并包含数组的形状。字符串
xwmevbvl4#
尝试给予plasma,因为它避免了串行化/并行化开销。
使用pip install pyarrow安装血浆
文档:https://arrow.apache.org/docs/python/plasma.html
首先,推出1gb内存的plasma [终端]:
plasma_store -m 100000000-s /tmp/plasma
字符串
写入时间:130 µs vs 782 µs(Redis实现:Mark Sethoff的回答)
通过使用plasma巨大页面可以改善写入时间,但仅适用于Linux机器:https://arrow.apache.org/docs/python/plasma.html#using-plasma-with-huge-pages
读取时间:31.2 µs vs 99.5 µs(Redis实现:Mark Sethoff的回答)
PS:代码在MacPro上运行
xt0899hw5#
tobytes()
函数的存储效率不是很高。为了减少必须写入redis服务器的存储,您可以使用base64包:字符串
@编辑:好的,由于Redis将值存储为字节字符串,因此直接存储字节字符串会更有效。但是,如果您将其转换为字符串,将其打印到控制台,或将其存储在文本文件中,则进行编码是有意义的。
dnph8jn46#
这是我从Jadiel de Armas修改的代码,他的代码几乎是正确的,只是缺少解码部分。我测试了它,它为我工作。
字符串