1. mars介绍
mars的主要目标就是让 Numpy、pandas 和 scikit-learn 等数据科学的库能够并行和分布式执行,充分利用多核和新的硬件。这里首先进行一下基准测试(CPU版本),由于pymars和jax都是惰性计算,因此时间使用的是打印数据出来的时间。总体来看,mars性能还是不错的。
时间(毫秒) | numpy | pymars | jax |
---|---|---|---|
生成5000^2随机数 | 409 | 184 | 244 |
5000^2矩阵相乘 | 1030 | 687 | 888 |
生成20000^2随机数并求和 | 4560 | 590 | 3270 |
2. mars基础
mars可以作为替代numpy的一个库,安装使用都很简单:
pip install pymars
2.1 使用mars.tensor模拟numpy
2.2 使用mars.dataframe模拟pandas
2.3 eager模式
用户可以通过选项启用 Eager 模式,在程序开头或控制台会话中设置选项。
>>> from mars.config import options
>>> options.eager_mode = True
或者使用上下文。
>>> from mars.config import option_context
>>> with option_context() as options:
>>> options.eager_mode = True
>>> # the eager mode is on only for the with statement
>>> ...
如果打开了 Eager 模式,则会在创建默认会话后立即执行 tensor 和 DataFrame 等等。
>>> import mars.tensor as mt
>>> import mars.dataframe as md
>>> from mars.config import options
>>> options.eager_mode = True
>>> t = mt.arange(6).reshape(2, 3)
>>> t
array([[0, 1, 2],
[3, 4, 5]])
>>> df = md.DataFrame(t)
>>> df.sum()
0 3
1 5
2 7
dtype: int64
3. 使用GPU
Tensor 通过指定 gpu=True 来指定在 GPU 上创建。创建 Tensor 和 随机抽样 中的方法都支持这个参数。
import mars.tensor as mt
a = mt.random.rand(10, 10, gpu=True) # indicate to create tensor on CUDA
a.sum().execute() # execution will happen on CUDA
记住,创建 tensor 的时候,并没有实际的 GPU 内存分配。当 .execute() 触发的时候,GPU 上才会有真正的内存分配和计算。
对于一个主存上创建的 tensor,调用 .to_gpu() 来指示把数据移至 GPU。
>>> b = mt.random.rand(10, 10) # indicate to create on main memory
>>> b = b.to_gpu() # indicate to move data to GPU memory
>>> b.sum().execute()
调用 .to_cpu() 来指示把数据移到主存。
>>> c = b.to_cpu() # b is allocated on GPU, move back to main memory
>>> c.sum().execute() # execution will happen on CPU
Mars 可以直接读取 CSV 文件至显存。
>>> import mars.dataframe as md
>>> df = md.read_csv('data.csv', gpu=True) # indicates to read csv into GPU memory
>>> df.groupby('a').sum().execute() # execution will happen on GPU
对于主存上的 DataFrame,调用 .to_gpu() 指示把数据移至显存。
>>> import mars.tensor as mt
>>> import mars.dataframe as md
>>> df = md.DataFrame(mt.random.rand(10, 10)) # indicate to create on main memory
>>> df = df.to_gpu() # indicate to move data to GPU memory
调用 .to_cpu() 来指示把数据移到主存。
>>> df2 = df.to_cpu() # df is allocated on GPU, move back to main memory
>>> df2.sum().execute() # execution will happen on CPU
4. 使用sklearn
4.1 并行化库joblib
首先进行注册:
from mars.learn.contrib.joblib import register_mars_backend
register_mars_backend()
接下来就可以使用了,用法类似tensorflow:
import joblib
import sklearn
from sklearn.datasets import load_digits
from sklearn.model_selection import RandomizedSearchCV
from sklearn.svm import SVC
from mars.learn.contrib.joblib import register_mars_backend
register_mars_backend()
digits = load_digits()
param_space = {
'C': np.logspace(-6, 6, 30),
'gamma': np.logspace(-8, 8, 30),
'tol': np.logspace(-4, -1, 30),
'class_weight': [None, 'balanced'],
}
model = SVC(kernel='rbf')
search = RandomizedSearchCV(model, param_space, cv=5, n_iter=10, verbose=10)
with joblib.parallel_backend('mars', service='http://<host>:<port>'):
search.fit(digits.data, digits.target)
4.2 lightgbm
首先安装lightgbm,下面是使用案例,首先加载数据:
from sklearn.datasets import load_boston
import mars.dataframe as md
boston = load_boston()
data = md.DataFrame(boston.data, columns=boston.feature_names)
from mars.learn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(data, boston.target, train_size=0.7, random_state=0)
接下来调用接口进行训练
from mars.learn.contrib import lightgbm as lgb
lg_reg = lgb.LGBMRegressor(colsample_bytree=0.3, learning_rate=0.1,max_depth=5, reg_alpha=10, n_estimators=10)
lg_reg.fit(X_train, y_train)
lg_reg.predict(X_test)
一旦一个集群存在,你可以要么设置默认 session,训练和预测就会自动提交到集群,要么你可以通过 session=*** 显示指定运行的 session:
from mars.session import new_session
# set the session as the default one
sess = new_session('http://<web_ip>:<web_port>').as_default()
lg_reg = lgb.LGBMRegressor()
# training will submitted to cluster by default
lg_reg.fit(X_train)
# Or, session could be specified as well
lg_reg.fit(X_train, session=sess)
4.3 其他
mars还可以和statsModels、tensorflow、xgboost集成
5. Mars remote
下面是一个例子,在需要并行的地方加上mr.spawn即可。
>>> import mars.remote as mr
>>>
>>> def add_one(x):
>>> return x + 1
>>>
>>> def sum_all(xs):
>>> return sum(xs)
>>>
>>> x_list = []
>>> for i in range(10):
>>> x_list.append(mr.spawn(add_one, args=(i,)))
>>> print(mr.spawn(sum_all, args=(x_list,)).execute().fetch())
下面是性能对比: