MLSQL 對Python的支援之路
前言
Python是做機器學習框架一定要支援的。MLSQL很早就支援整合Python指令碼做模型的訓練和預測。
訓練的使用方式:
load libsvm.`sample_libsvm_data.txt` as data; train data as PythonAlg.`/tmp/model1` where pythonScriptPath="/tmp/train.py" -- keep the vertion of every model you train and keepVersion="true" andenableDataLocal="true" anddataLocalFormat="json" and`fitParam.0.batchSize`="1000" and`fitParam.0.labelSize`="2" and validateTable="data" and `systemParam.pythonPath`="python" and `systemParam.pythonVer`="2.7" and `kafkaParam.bootstrap.servers`="127.0.0.1:9092" ;
可以看到,你可以直接指定一個python指令碼路徑。預測也是同樣的:
load libsvm.`sample_libsvm_data.txt` as data; -- register the model we have trained as a funciton. register PythonAlg.`/tmp/model1` as npredict options pythonScriptPath="/tmp/predict.py" ; -- use the predict udf select npredict(features) from data as newdata;
問題
前面的支援方式有三個巨大的缺陷,我們在實際使用過程中也是體會明顯:
- 沒有解決Python環境問題。因為是常駐服務模式,讓問題變得更加複雜。
- 沒有專案的概念。對於自己實現的複雜演算法,不大可能放在一個指令碼中,而且預測指令碼和訓練指令碼往往會依賴一堆的基礎指令碼。
- 沒有區分批預測和API預測。批預測適合在批處理或者流式計算中使用。API預測則適合部署成http 介面。
解決辦法
- 通過conda解決環境問題,每個專案有自己的python執行環境。
- 提出專案的概念,即使配置的是一個指令碼,系統也會自動生成一個專案來執行。
- 以MLFlow為藍本,指定了一個專案的標準。標準專案應該在根目錄有一個MLproject描述檔案。
具體示例專案可以參看ofollow,noindex">這裡 ,對應的MLproject檔案如下:
name: tutorial conda_env: conda.yaml entry_points: main: train: parameters: alpha: {type: float, default: 0.5} l1_ratio: {type: float, default: 0.1} command: "python train.py 0.5 0.1" batch_predict: parameters: alpha: {type: float, default: 0.5} l1_ratio: {type: float, default: 0.1} command: "python batchPredict.py" api_predict: parameters: alpha: {type: float, default: 0.5} l1_ratio: {type: float, default: 0.1} command: "python predict.py"
使用者需要提供三個核心指令碼:批處理,批預測,API預測。具體如何寫可以看看示例專案。我們現在來看看怎麼使用這個專案:
首先是訓練部分:
load csv.`/Users/allwefantasy/CSDNWorkSpace/mlflow/examples/sklearn_elasticnet_wine/wine-quality.csv` where header="true" and inferSchema="true" as data; train data as PythonAlg.`/tmp/abc` where pythonScriptPath="/Users/allwefantasy/CSDNWorkSpace/mlflow/examples/sklearn_elasticnet_wine" and keepVersion="true" andenableDataLocal="true" anddataLocalFormat="csv" ;
非常簡單,你只要指定專案地址即可。接著我們做批量預測:
predict data as PythonAlg.`/tmp/abc`;
這裡我們無需指定專案地址,原因是在/tmp/abc裡已經儲存了所有需要的元資料。
接著我們部署一個API服務 ,
通過http介面利用如下語句註冊模型:
register PythonAlg.`/tmp/abc` as pj;
接著就可以預測了(我寫了段程式模擬請求)
import org.apache.http.client.fluent.{Form, Request} object Test { def main(args: Array[String]): Unit = { val sql = "select pj(vec_dense(features)) as p1 " val res = Request.Post("http://127.0.0.1:9003/model/predict").bodyForm(Form.form(). add("sql", sql). add("data", s"""[{"features":[ 0.045, 8.8, 1.001, 45.0, 7.0, 170.0, 0.27, 0.45, 0.36, 3.0, 20.7 ]}]"""). add("dataType", "row") .build()).execute().returnContent().asString() println(res) } }
完成。