很高興在這裏宣佈咱們的新項目:Mars,一個基於矩陣的統一分佈式計算框架。咱們已經在 Github 開源:https://github.com/mars-project/mars 。python
Python 是一門至關古老的語言了,現在,在數據科學計算、機器學習、以及深度學習領域,Python 愈來愈受歡迎。c++
大數據領域,因爲 hadoop 和 spark 等,Java 等仍是佔據着比較核心的位置,可是在 spark 上也能夠看到,pyspark 的用戶佔據很大一部分。git
深度學習領域,絕大部分的庫(tensorflow、pytorch、mxnet、chainer)都支持 Python 語言,且 Python 語言也是這些庫上使用最普遍的語言。github
對 MaxCompute 來講,Python 用戶也是一股重要力量。算法
Python 在數據科學領域,有很是豐富的包能夠選擇,下圖展現了整個 Python 數據科學技術棧。後端
能夠看到 numpy 做爲基礎,在其上,有 scipy 面向科學家,pandas 面向數據分析,scikit-learn 則是最著名的機器學習庫,matplotlib 專一於可視化。數組
對 numpy 來講,其中最核心的概念就是 ndarray——多維數組,pandas、scikit-learn 等庫都構建於這個數據結構基礎之上。數據結構
雖然 Python 在這些領域愈來愈流行,PyData 技術棧給數據科學家們提供了多維矩陣、DataFrame 上的分析和計算能力、基於二維矩陣的機器學習算法,但這些庫都僅僅受限於單機運算,在大數據時代,數據量一大,這些庫的處理能力都顯得捉襟見肘。框架
雖然大數據時代,有各類各樣基於 SQL 的計算引擎,但對科學計算領域,這些引擎都不太適合用來進行大規模的多維矩陣的運算操做。並且,至關一部分用戶,尤爲是數據科學家們,習慣於使用各類成熟的單機庫,他們不但願改變本身的使用習慣,去學習一些新的庫和語法。dom
此外,在深度學習領域,ndarray/tensor 也是最基本的數據結構,但它們僅僅限制在深度學習上,也不適合大規模的多維矩陣運算。
基於這些考量,咱們開發了 Mars,一個基於 tensor 的統一分佈式計算框架,前期咱們關注怎麼將 tensor 這層作到極致。
Mars 的核心用 python 實現,這樣作的好處是能利用到現有的 Python 社區的工做,咱們能充分利用 numpy、cupy、pandas 等來做爲咱們小的計算單元,咱們能快速穩定構建咱們整個系統;其次,Python 自己能輕鬆和 c/c++ 作繼承,咱們也沒必要擔憂 Python 語言自己的性能問題,咱們能夠對性能熱點模塊輕鬆用 c/cython 重寫。
接下來,主要集中介紹 Mars tensor,即多維矩陣計算的部分。
Numpy 成功的一個緣由,就是其簡單易用的 API。Mars tensor 在這塊能夠直接利用其做爲咱們的接口。因此在 numpy API 的基礎上,用戶能夠寫出靈活的代碼,進行數據處理,甚至是實現各類算法。
下面是兩段代碼,分別是用 numpy 和 Mars tensor 來實現一個功能。
import numpy as np a = np.random.rand(1000, 2000) (a + 1).sum(axis=1)
import mars.tensor as mt a = mt.random.rand(1000, 2000) (a + 1).sum(axis=1).execute()
這裏,建立了一個 1000x2000 的隨機數矩陣,對其中每一個元素加1,並在 axis=1(行)上求和。
目前,Mars 實現了大約 70% 的 Numpy 經常使用接口。
能夠看到,除了 import 作了替換,用戶只須要經過調用 execute 來顯式觸發計算。經過 execute 顯式觸發計算的好處是,咱們能對中間過程作更多的優化,來更高效地執行計算。
不過,靜態圖的壞處是犧牲了靈活性,增長了 debug 的難度。下個版本,咱們會提供 instant/eager mode,來對每一步操做觸發計算,這樣,用戶能更有效地進行 debug,且能利用到 Python 語言來作循環,固然性能也會有所損失。
Mars tensor 也支持使用 GPU 計算。對於某些矩陣建立的接口,咱們提供了 gpu=True
的選項,來指定分配到 GPU,後續這個矩陣上的計算將會在 GPU 上進行。
import mars.tensor as mt a = mt.random.rand(1000, 2000, gpu=True) (a + 1).sum(axis=1).execute()
這裏 a
是分配在 GPU 上,所以後續的計算在 GPU 上進行。
Mars tensor 支持建立稀疏矩陣,不過目前 Mars tensor 還只支持二維稀疏矩陣。好比,咱們能夠建立一個稀疏的單位矩陣,經過指定 sparse=True
便可。
import mars.tensor as mt a = mt.eye(1000, sparse=True, gpu=True) b = (a + 1).sum(axis=1)
這裏看到,gpu 和 sparse 選項能夠同時指定。
這部分在 Mars 裏還沒有實現,這裏提下咱們但願在 Mars 上構建的各個組件。
相信有部分同窗也知道 PyODPS DataFrame,這個庫是咱們以前的一個項目,它能讓用戶寫出相似 pandas 相似的語法,讓運算在 ODPS 上進行。但 PyODPS DataFrame 因爲 ODPS 自己的限制,並不能徹底實現 pandas 的所有功能(如 index 等),並且語法也有不一樣。
基於 Mars tensor,咱們提供 100% 兼容 pandas 語法的 DataFrame。使用 mars DataFrame,不會受限於單個機器的內存。這個是咱們下個版本的最主要工做之一。
scikit-learn 的一些算法的輸入就是二維的 numpy ndarray。咱們也會在 Mars 上提供分佈式的機器學習算法。咱們大體有如下三條路:
Mars 的核心,實際上是一個基於 Actor 的細粒度的調度引擎。所以,實際上,用戶能夠寫一些並行的 Python 函數和類,來進行細粒度的控制。咱們可能會提供如下幾種接口。
函數
用戶能寫普通的 Python 函數,經過 mars.remote.spawn
來將函數調度到 Mars 上來分佈式運行
import mars.remote as mr def add(x, y): return x + y data = [ (1, 2), (3, 4) ] for item in data: mr.spawn(add, item[0], item[1])
利用 mr.spawn
,用戶能輕鬆構建分佈式程序。在函數裏,用戶也可使用 mr.spawn,這樣,用戶能夠寫出很是精細的分佈式執行程序。
類
有時候,用戶須要一些有狀態的類,來進行更新狀態等操做,這些類在 Mars 上被稱爲 RemoteClass。
import mars.remote as mr class Counter(mr.RemoteClass): def __init__(self): self.value = 0 def inc(self, n=1): self.value += n counter = mr.spawn(Counter) counter.inc()
目前,這些函數和類的部分還沒有實現,只是在構想中,因此屆時接口可能會作調整。
這裏,我簡單介紹下 Mars tensor 的內部原理。
在客戶端,咱們不會作任何真正的運算操做,用戶寫下代碼,咱們只會在內存裏用圖記錄用戶的操做。
對於 Mars tensor 來講,咱們有兩個重要的概念,operand 和 tensor,分別以下圖的藍色圓和粉色方塊所示。Operand 表示算子,tensor 表示生成的多維數組。
好比,下圖,用戶寫下這些代碼,咱們會依次在圖上生成對應的 operand 和 tensor。
當用戶顯式調用 execute
的時候,咱們會將這個圖提交到 Mars 的分佈式執行環境。
咱們客戶端部分,並不會對語言有任何依賴,只須要有相同的 tensor graph 序列化,所以能夠用任何語言實現。下個版本咱們要不要提供 Java 版本的 Mars tensor,咱們還要看是否是有用戶須要。
Mars 本質上是一個對細粒度圖的執行調度系統。
對於 Mars tensor 來講,咱們接收到了客戶端的 tensor 級別的圖(粗粒度),咱們要嘗試將其轉化成 chunk 級別的圖(細粒度)。每一個 chunk 以及其輸入,在執行時,都應當能被內存放下。咱們稱這個過程叫作 tile。
在拿到細粒度的 chunk 級別的圖後,咱們會將這個圖上的 Operand 分配到各個 worker 上去執行。
Mars 在九月份的雲棲大會發布,目前咱們已經在 Github 開源:https://github.com/mars-project/mars。咱們項目徹底以開源的方式運做,而不是簡單把代碼放出來。
期待有更多的同窗能參與 Mars,共建 Mars。
努力了好久,咱們不會甘於作一個平庸的項目,咱們期待對世界作出一點微小的貢獻——咱們的征途是星辰大海!
本文爲雲棲社區原創內容,未經容許不得轉載。