一個(gè)嵌套并行的簡(jiǎn)單例子。一個(gè)應(yīng)用運(yùn)行兩個(gè)并行實(shí)驗(yàn)(每個(gè)都是長(zhǎng)時(shí)間運(yùn)行任務(wù)),每個(gè)實(shí)驗(yàn)運(yùn)行一定數(shù)量的并行模擬(每一個(gè)同時(shí)也是一個(gè)任務(wù))。

Ray 有兩種主要使用方法:通過低級(jí) API 或高級(jí)庫。高級(jí)庫是構(gòu)建在低級(jí) API 之上的。目前它們包括 Ray RLlib,一個(gè)可擴(kuò)展強(qiáng)化學(xué)習(xí)庫;和 Ray.tune,一個(gè)高效分布式超參數(shù)搜索庫。

Ray 的低層 API

開發(fā) Ray API 的目的是讓我們能更自然地表達(dá)非常普遍的計(jì)算模式和應(yīng)用,而不被限制為固定的模式,就像 MapReduce 那樣。

動(dòng)態(tài)任務(wù)圖

Ray 應(yīng)用的基礎(chǔ)是動(dòng)態(tài)任務(wù)圖。這和 TensorFlow 中的計(jì)算圖很不一樣。TensorFlow 的計(jì)算圖用于表征神經(jīng)網(wǎng)絡(luò),在單個(gè)應(yīng)用中執(zhí)行很多次,而 Ray 的任務(wù)圖用于表征整個(gè)應(yīng)用,并僅執(zhí)行一次。任務(wù)圖對(duì)于前臺(tái)是未知的,隨著應(yīng)用的運(yùn)行而動(dòng)態(tài)地構(gòu)建,且一個(gè)任務(wù)的執(zhí)行可能創(chuàng)建更多的任務(wù)。

計(jì)算圖示例。白色橢圓表示任務(wù),藍(lán)色方框表示對(duì)象。箭頭表示任務(wù)依賴于一個(gè)對(duì)象,或者任務(wù)創(chuàng)建了一個(gè)對(duì)象。

任意的 Python 函數(shù)都可以當(dāng)成任務(wù)來執(zhí)行,并且可以任意地依賴于其它任務(wù)的輸出。如下示例代碼所示:

# Define two remote functions. Invocations of these functions create tasks

# that are executed remotely.

@ray
.
remote

def
multiply
(
x
,
y
):

return
np
.
dot
(
x
,
y
)

@ray
.
remote

def
zeros
(
size
):

return
np
.
zeros
(
size
)

# Start two tasks in parallel. These immediately return futures and the

# tasks are executed in the background.

x_id
=
zeros
.
remote
((
100
,

100
))

y_id
=
zeros
.
remote
((
100
,

100
))

# Start a third task. This will not be scheduled until the first two

# tasks have completed.

z_id
=
multiply
.
remote
(
x_id
,
y_id
)

# Get the result. This will block until the third task completes.

z
=
ray
.
get
(
z_id
)

動(dòng)作器(Actor)

僅用遠(yuǎn)程函數(shù)和上述的任務(wù)所無法完成的一件事是在相同的共享可變狀態(tài)上執(zhí)行多個(gè)任務(wù)。這在很多機(jī)器學(xué)習(xí)場(chǎng)景中都出現(xiàn)過,其中共享狀態(tài)可能是模擬器的狀態(tài)、神經(jīng)網(wǎng)絡(luò)的權(quán)重或其它。Ray 使用 actor 抽象以封裝多個(gè)任務(wù)之間共享的可變狀態(tài)。以下是關(guān)于 Atari 模擬器的虛構(gòu)示例:

import
gym

@ray
.
remote

class

Simulator
(
object
):

def
__init__
(
self
):

self
.
env
=
gym
.
make
(
"Pong-v0"
)

self
.
env
.
reset
()

def
step
(
self
,
action
):

return
self
.
env
.
step
(
action
)

# Create a simulator, this will start a remote process that will run

# all methods for this actor.

simulator
=

Simulator
.
remote
()

observations
=

[]

for
_
in
range
(
4
):

# Take action 0 in the simulator. This call does not block and

# it returns a future.

observations
.
append
(
simulator
.
step
.
remote
(
0
))

Actor 可以很靈活地應(yīng)用。例如,actor 可以封裝模擬器或神經(jīng)網(wǎng)絡(luò)策略,并且可以用于分布式訓(xùn)練(作為參數(shù)服務(wù)器),或者在實(shí)際應(yīng)用中提供策略。

圖左:actor 為客戶端進(jìn)程提供預(yù)測(cè)/操作。圖右:多個(gè)參數(shù)服務(wù)器 actor 使用多個(gè)工作進(jìn)程執(zhí)行分布式訓(xùn)練。

參數(shù)服務(wù)器示例

一個(gè)參數(shù)服務(wù)器可以作為一個(gè) Ray actor 按如下代碼實(shí)現(xiàn):

@ray
.
remote

class

ParameterServer
(
object
):

def
__init__
(
self
,
keys
,
values
):

# These values will be mutated, so we must create a local copy.

values
=

[
value
.
copy
()

for
value
in
values
]

self
.
parameters
=
dict
(
zip
(
keys
,
values
))

def
get
(
self
,
keys
):

return

[
self
.
parameters
[
key
]

for
key
in
keys
]

def
update
(
self
,
keys
,
values
):

# This update function adds to the existing values, but the update

# function can be defined arbitrarily.

for
key
,
value
in
zip
(
keys
,
values
):

self
.
parameters
[
key
]

+=
value

這里有更完整的示例:http://ray.readthedocs.io/en/latest/example-parameter-server.html

執(zhí)行以下代碼初始化參數(shù)服務(wù)器:

parameter_server 
=

ParameterServer
.
remote
(
initial_keys
,
initial_values
)

執(zhí)行以下代碼,創(chuàng)建 4 個(gè)長(zhǎng)時(shí)間運(yùn)行的持續(xù)恢復(fù)和更新參數(shù)的工作進(jìn)程:

@ray
.
remote

def
worker_task
(
parameter_server
):

while

True
:

keys
=

[
'key1'
,

'key2'
,

'key3'
]

# Get the latest parameters.

values
=
ray
.
get
(
parameter_server
.
get
.
remote
(
keys
))

# Compute some parameter updates.

updates
=



# Update the parameters.

parameter_server
.
update
.
remote
(
keys
,
updates
)

# Start 4 long-running tasks.

for
_
in
range
(
4
):

worker_task
.
remote
(
parameter_server
)

Ray 高級(jí)庫

Ray RLib 是一個(gè)可擴(kuò)展的強(qiáng)化學(xué)習(xí)庫,其建立的目的是在多個(gè)機(jī)器上運(yùn)行,可以通過示例訓(xùn)練腳本或者 Python API 進(jìn)行使用。目前它已有的實(shí)現(xiàn)為:

UC Berkeley 的開發(fā)者在未來將繼續(xù)添加更多的算法。同時(shí),RLib 和 OpenAI gym 是完全兼容的。

Ray.tune 是一個(gè)高效的分布式超參數(shù)搜索庫。它提供了一個(gè) Python API 以執(zhí)行深度學(xué)習(xí)、強(qiáng)化學(xué)習(xí)和其它計(jì)算密集型任務(wù)。以下是一個(gè)虛構(gòu)示例的代碼:

from
ray
.
tune
import
register_trainable
,
grid_search
,
run_experiments

# The function to optimize. The hyperparameters are in the config

# argument.

def
my_func
(
config
,
reporter
):

import
time
,
numpy
as
np

i
=

0

while

True
:

reporter
(
timesteps_total
=
i
,
mean_accuracy
=(
i
**
config
[
'alpha'
]))

i
+=
config
[
'beta'
]

time
.
sleep
(
0.01
)

register_trainable
(
'my_func'
,
my_func
)

run_experiments
({

'my_experiment'
:

{

'run'
:

'my_func'
,

'resources'
:

{
'cpu'
:

1
,

'gpu'
:

0
},

'stop'
:

{
'mean_accuracy'
:

100
},

'config'
:

{

'alpha'
:
grid_search
([
0.2
,

0.4
,

0.6
]),

'beta'
:
grid_search
([
1
,

2
]),

},

}

})

可以使用 TensorBoard 和 rllab’s VisKit 等工具對(duì)運(yùn)行狀態(tài)的結(jié)果進(jìn)行實(shí)時(shí)可視化(或者直接閱讀 JSON 日志)。Ray.tune 支持網(wǎng)格搜索、隨機(jī)搜索和更復(fù)雜的早停算法,如 HyperBand。

本文章轉(zhuǎn)載微信公眾號(hào)@機(jī)器之心

上一篇:

數(shù)據(jù)庫融入DevOps基因后,運(yùn)維再也不用做背鍋俠了!

下一篇:

LLM之RAG實(shí)戰(zhàn)|? 高級(jí)RAG:通過使用LlamaIndex重新排序來提高檢索效率
#你可能也喜歡這些API文章!

我們有何不同?

API服務(wù)商零注冊(cè)

多API并行試用

數(shù)據(jù)驅(qū)動(dòng)選型,提升決策效率

查看全部API→
??

熱門場(chǎng)景實(shí)測(cè),選對(duì)API

#AI文本生成大模型API

對(duì)比大模型API的內(nèi)容創(chuàng)意新穎性、情感共鳴力、商業(yè)轉(zhuǎn)化潛力

25個(gè)渠道
一鍵對(duì)比試用API 限時(shí)免費(fèi)

#AI深度推理大模型API

對(duì)比大模型API的邏輯推理準(zhǔn)確性、分析深度、可視化建議合理性

10個(gè)渠道
一鍵對(duì)比試用API 限時(shí)免費(fèi)