Stay Hungry,Stay Foolish!

Ray - Fast and Simple Distributed Computing

Ray

https://ray.io/

https://github.com/ray-project/ray

(1)机器学习生态基于python语言,但是python具有全局解释器锁缺点,限制了对单台机器的多核的利用

(2)同时查大规模模型的数据的出现,需要依赖集群来解决类似问题,引入了分布式机器学习的需求,

但是不需要引入更加高层的应用(spark)的基础上,ray基于python生态,单程的简单的分布式计算框架。

 

ray同时也包括了机器学习应用。

Ray provides a simple, universal API for building distributed applications.

Ray is packaged with the following libraries for accelerating machine learning workloads:

  • Tune: Scalable Hyperparameter Tuning
  • RLlib: Scalable Reinforcement Learning
  • RaySGD: Distributed Training Wrappers
  • Ray Serve: Scalable and Programmable Serving

 

https://docs.ray.io/en/latest/index.html

Ray provides a simple, universal API for building distributed applications.

Ray accomplishes this mission by:

  1. Providing simple primitives for building and running distributed applications.

  2. Enabling end users to parallelize single machine code, with little to zero code changes.

  3. Including a large ecosystem of applications, libraries, and tools on top of the core Ray to enable complex applications.

 

https://www.ctolib.com/topics-138457.html

传统编程依赖于两个核心概念:函数和类。使用这些构建块就可以构建出无数的应用程序。

但是,当我们将应用程序迁移到分布式环境时,这些概念通常会发生变化。

一方面,OpenMPI、Python 多进程和 ZeroMQ 等工具提供了用于发送和接收消息的低级原语。这些工具非常强大,但它们提供了不同的抽象,因此要使用它们就必须从头开始重写单线程应用程序。

另一方面,我们也有一些特定领域的工具,例如用于模型训练的 TensorFlow、用于数据处理且支持 SQL 的 Spark,以及用于流式处理的 Flink。这些工具提供了更高级别的抽象,如神经网络、数据集和流。但是,因为它们与用于串行编程的抽象不同,所以要使用它们也必须从头开始重写应用程序。

取代 Python 多进程!伯克利开源分布式框架 Ray 用于分布式计算的工具

Ray 占据了一个独特的中间地带。它并没有引入新的概念,而是采用了函数和类的概念,并将它们转换为分布式的任务和 actor。Ray 可以在不做出重大修改的情况下对串行应用程序进行并行化。

 

来源(论文)

https://arxiv.org/abs/1703.03924

 

Real-Time Machine Learning: The Missing Pieces

Machine learning applications are increasingly deployed not only to serve predictions using static models, but also as tightly-integrated components of feedback loops involving dynamic, real-time decision making. These applications pose a new set of requirements, none of which are difficult to achieve in isolation, but the combination of which creates a challenge for existing distributed execution frameworks: computation with millisecond latency at high throughput, adaptive construction of arbitrary task graphs, and execution of heterogeneous kernels over diverse sets of resources. We assert that a new distributed execution framework is needed for such ML applications and propose a candidate approach with a proof-of-concept architecture that achieves a 63x performance improvement over a state-of-the-art execution framework for a representative application.

 

架构

https://www.cnblogs.com/fanzhidongyzby/p/7901139.html

论文给出的架构图里并未画出Driver的概念,因此我在其基础上做了一些修改和扩充。

Ray的Driver节点和和Slave节点启动的组件几乎相同,不过却有以下区别:

  1. Driver上的工作进程DriverProcess一般只有一个,即用户启动的PythonShell。Slave可以根据需要创建多个WorkerProcess。
  2. Driver只能提交任务,却不能接收来自全局调度器分配的任务。Slave可以提交任务,也可以接收全局调度器分配的任务。
  3. Driver可以主动绕过全局调度器给Slave发送Actor调用任务(此处设计是否合理尚不讨论)。Slave只能接收全局调度器分配的计算任务。

 

https://zhuanlan.zhihu.com/p/41875076

其中的原理是将代码序列化到 redis 上存储为 object (object 可以理解为高效的不可变对象和数据共享),实现各种异步执行和数据交换,优先在本地节点完成任务,如果完不成再由global scheduler 调配到其它节点(更正补充)。

 

DEMO CODE

单机版本,分布式任务示例。

remote声明函数为一个任务。

remote调用会将任务分发到一个计算进程中,并执行。

import ray
ray.init()

@ray.remote
def f(x):
    return x * x

futures = [f.remote(i) for i in range(4)]
print(ray.get(futures))

 

 

聚类学习工作流改造

https://github.com/fanqingsong/machine_learning_workflow_on_ray

from csv import reader
from sklearn.cluster import KMeans
import joblib
import ray


ray.init()


# Load a CSV file
def load_csv(filename):
    file = open(filename, "rt")
    lines = reader(file)
    dataset = list(lines)
    return dataset

# Convert string column to float
def str_column_to_float(dataset, column):
    for row in dataset:
        row[column] = float(row[column].strip())

# Convert string column to integer
def str_column_to_int(dataset, column):
    class_values = [row[column] for row in dataset]
    unique = set(class_values)
    lookup = dict()
    for i, value in enumerate(unique):
        lookup[value] = i
    for row in dataset:
        row[column] = lookup[row[column]]
    return lookup

def getRawIrisData():
    # Load iris dataset
    filename = 'iris.csv'
    dataset = load_csv(filename)
    print('Loaded data file {0} with {1} rows and {2} columns'.format(filename, len(dataset), len(dataset[0])))
    print(dataset[0])
    # convert string columns to float
    for i in range(4):
        str_column_to_float(dataset, i)
    # convert class column to int
    lookup = str_column_to_int(dataset, 4)
    print(dataset[0])
    print(lookup)

    return dataset

@ray.remote
def getTrainData():
    dataset = getRawIrisData()
    trainData = [ [one[0], one[1], one[2], one[3]] for one in dataset ]

    return trainData

@ray.remote
def getNumClusters():
    return 3

@ray.remote
def train(numClusters, trainData):
    print("numClusters=%d" % numClusters)

    model = KMeans(n_clusters=numClusters)

    model.fit(trainData)

    # save model for prediction
    joblib.dump(model, 'model.kmeans')

    return trainData

@ray.remote
def predict(irisData):
    # test saved prediction
    model = joblib.load('model.kmeans')

    # cluster result
    labels = model.predict(irisData)

    print("cluster result")
    print(labels)


def machine_learning_workflow_pipeline():
    trainData = getTrainData.remote()
    numClusters = getNumClusters.remote()
    trainData = train.remote(numClusters, trainData)
    result = predict.remote(trainData)

    result = ray.get(result)
    print("result=", result)



if __name__ == "__main__":
    machine_learning_workflow_pipeline()

 

 

Ray 破冰学习

https://github.com/anyscale/academy/blob/master/ray-crash-course/00-Ray-Crash-Course-Overview.ipynb

 

 

Ray 在b站应用

https://mp.weixin.qq.com/s/m9V3nwGgjQkOxbtJI4UMGg

2. Ray 概述

Ray 主要包含 Core 和 AI Runtime 两大部分。在 Core 层面,它具备异构计算能力,能够实现 GPU 与 CPU 的协同工作,同时支持细粒度并行计算,将并行粒度细化到函数级。而 AI Runtime 则是面向 AI 链路,提供从一端到另一端的整套生态解决方案,为 AI 相关任务提供全面支持。

图片

3. Ray 计算原语

在 Ray 的计算体系中,计算原语遵循“一切皆为 Actor、Task” 的理念,并且秉持“Python First” 原则,这使得其在开发过程中能紧密贴近算法开发,极大地方便了算法开发者。与之配套的状态存储,采用 Object Store(Plasma)来实现。此外,Global Control Service 扮演着重要角色,它负责存放 Actor、Task 的元信息,进而实现对整个计算过程的血缘管理,确保计算过程的可追溯性与有序性。

图片

图片

4. Iceberg 概述

Iceberg 是一种融合湖仓优势的解决方案。它具备湖仓一体特性,可实现统一存储,无论是非结构化数据、结构化数据还是元信息,都能整合存储。Iceberg 表格式更是功能强大,不仅支持 ACID 事务及版本控制,确保数据操作的一致性与可追溯性,还着重于元数据管理,有效应对 AI 数据管理难题。同时,它提供 TimeTravel 功能,凭借时间戳或版本号回溯数据,满足不同场景下的数据追溯需求。此外,通过优化数据组织与布局、增强索引等方式,实现高性能查询,为数据处理和分析提供有力支持。

图片

5. PyIceberg

Iceberg 针对 AI,做 PyIceberg 扩展,包含 DuckDB、pandas、daft、Ray 等等。

图片

6. 整体架构

整体架构由接入层、任务编排、异构计算资源、资源管控、底层资源池构成。在接入层,采用标准化接入方式,涵盖 API、WorkFlow、event - driven 以及 Batch,确保各类数据与任务能顺利接入。任务编排环节,依托 Ray Data 完善 Source/Sink,并提供如分片、抽帧、OCR、ASR 等通用领域算子,实现任务的合理编排与处理。资源管控调度基于 K8s 多资源池,通过封装 Ray 的 Session 和 Job 模式,对异构计算资源和底层资源池进行有效管理与调度,保障系统的高效稳定运行。

图片

7. 典型计算范式

在典型计算范式中,针对多模态计算范式有着特定的处理流程。首先,借助 Iceberg 读取业务相关视频,这些视频的初步处理运行在配备 CPU 资源的 Ray Actor 中,通过读取 SQL 获取特定条件,进而对视频进行视频切片与抽帧操作。在此过程中,目录下的视频文件会进行装箱处理,并且支持断点处理,利用一个大小为 10G 的持久化队列来记录处理进度并保持实时更新。随后,配备 GPU 资源的 Ray Actor 进一步对相关信息(message)进行处理,具体包括对视频切片开展推理、生成 caption,对图片执行 OCR、进行美学评分等操作。之后,执行结果信息会被推送给配备 CPU 资源的 Ray Actor,由其汇总每个视频的标注数据,这些数据涵盖  OCR、评分、caption 等内容,最后将其持久化写入 Iceberg。此外,该计算范式还包含不同的服务模式。其中,Serve 用于业务服务化,通过对外暴露 API 实现接入;Per - Job 模式下,一个 Job 对应一个 Cluster,既可以运行流处理任务,也能运行批处理任务;而 Multi - Job 模式则是多个 Job 共用一个 Cluster,以此实现资源的复用与预热(warmup)。

图片

8

 

posted @ 2020-10-14 14:51  lightsong  阅读(378)  评论(0)    收藏  举报
千山鸟飞绝,万径人踪灭