|
|
@ -17,35 +17,34 @@ |
|
|
|
|
|
|
|
|
|
|
|
package org.apache.dolphinler.plugin.task.mlflow; |
|
|
|
package org.apache.dolphinler.plugin.task.mlflow; |
|
|
|
|
|
|
|
|
|
|
|
import java.util.Date; |
|
|
|
|
|
|
|
import java.util.UUID; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import org.apache.dolphinscheduler.plugin.task.api.TaskExecutionContext; |
|
|
|
import org.apache.dolphinscheduler.plugin.task.api.TaskExecutionContext; |
|
|
|
import org.apache.dolphinscheduler.plugin.task.api.TaskExecutionContextCacheManager; |
|
|
|
import org.apache.dolphinscheduler.plugin.task.api.TaskExecutionContextCacheManager; |
|
|
|
import org.apache.dolphinscheduler.plugin.task.api.utils.OSUtils; |
|
|
|
|
|
|
|
import org.apache.dolphinscheduler.plugin.task.mlflow.MlflowConstants; |
|
|
|
import org.apache.dolphinscheduler.plugin.task.mlflow.MlflowConstants; |
|
|
|
import org.apache.dolphinscheduler.plugin.task.mlflow.MlflowParameters; |
|
|
|
import org.apache.dolphinscheduler.plugin.task.mlflow.MlflowParameters; |
|
|
|
import org.apache.dolphinscheduler.plugin.task.mlflow.MlflowTask; |
|
|
|
import org.apache.dolphinscheduler.plugin.task.mlflow.MlflowTask; |
|
|
|
|
|
|
|
import org.apache.dolphinscheduler.spi.utils.JSONUtils; |
|
|
|
|
|
|
|
import org.apache.dolphinscheduler.spi.utils.PropertyUtils; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import java.util.Date; |
|
|
|
|
|
|
|
import java.util.UUID; |
|
|
|
|
|
|
|
|
|
|
|
import org.junit.Assert; |
|
|
|
import org.junit.Assert; |
|
|
|
import org.junit.Before; |
|
|
|
import org.junit.Before; |
|
|
|
import org.junit.Test; |
|
|
|
import org.junit.Test; |
|
|
|
|
|
|
|
import org.junit.runner.RunWith; |
|
|
|
import org.mockito.Mockito; |
|
|
|
import org.mockito.Mockito; |
|
|
|
import org.powermock.api.mockito.PowerMockito; |
|
|
|
import org.powermock.api.mockito.PowerMockito; |
|
|
|
import org.slf4j.Logger; |
|
|
|
|
|
|
|
import org.slf4j.LoggerFactory; |
|
|
|
|
|
|
|
import org.apache.dolphinscheduler.spi.utils.PropertyUtils; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import org.powermock.core.classloader.annotations.PrepareForTest; |
|
|
|
|
|
|
|
import org.powermock.core.classloader.annotations.PowerMockIgnore; |
|
|
|
import org.powermock.core.classloader.annotations.PowerMockIgnore; |
|
|
|
import org.junit.runner.RunWith; |
|
|
|
import org.powermock.core.classloader.annotations.PrepareForTest; |
|
|
|
import org.powermock.modules.junit4.PowerMockRunner; |
|
|
|
|
|
|
|
import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor; |
|
|
|
import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor; |
|
|
|
import org.apache.dolphinscheduler.spi.utils.JSONUtils; |
|
|
|
import org.powermock.modules.junit4.PowerMockRunner; |
|
|
|
|
|
|
|
import org.slf4j.Logger; |
|
|
|
|
|
|
|
import org.slf4j.LoggerFactory; |
|
|
|
|
|
|
|
|
|
|
|
@RunWith(PowerMockRunner.class) |
|
|
|
@RunWith(PowerMockRunner.class) |
|
|
|
@PrepareForTest({ |
|
|
|
@PrepareForTest({ |
|
|
|
JSONUtils.class, |
|
|
|
JSONUtils.class, |
|
|
|
PropertyUtils.class, |
|
|
|
PropertyUtils.class, |
|
|
|
}) |
|
|
|
}) |
|
|
|
@PowerMockIgnore({"javax.*"}) |
|
|
|
@PowerMockIgnore({"javax.*"}) |
|
|
|
@SuppressStaticInitializationFor("org.apache.dolphinscheduler.spi.utils.PropertyUtils") |
|
|
|
@SuppressStaticInitializationFor("org.apache.dolphinscheduler.spi.utils.PropertyUtils") |
|
|
@ -81,84 +80,85 @@ public class MlflowTaskTest { |
|
|
|
public void testInitBasicAlgorithmTask() { |
|
|
|
public void testInitBasicAlgorithmTask() { |
|
|
|
MlflowTask mlflowTask = initTask(createBasicAlgorithmParameters()); |
|
|
|
MlflowTask mlflowTask = initTask(createBasicAlgorithmParameters()); |
|
|
|
Assert.assertEquals(mlflowTask.buildCommand(), |
|
|
|
Assert.assertEquals(mlflowTask.buildCommand(), |
|
|
|
"export MLFLOW_TRACKING_URI=http://127.0.0.1:5000\n" + |
|
|
|
"export MLFLOW_TRACKING_URI=http://127.0.0.1:5000\n" |
|
|
|
"data_path=/data/iris.csv\n" + |
|
|
|
+ "data_path=/data/iris.csv\n" |
|
|
|
"repo=https://github.com/apache/dolphinscheduler-mlflow#Project-BasicAlgorithm\n" + |
|
|
|
+ "repo=dolphinscheduler-mlflow#Project-BasicAlgorithm\n" |
|
|
|
"mlflow run $repo " + |
|
|
|
+ "git clone https://github.com/apache/dolphinscheduler-mlflow dolphinscheduler-mlflow\n" |
|
|
|
"-P algorithm=xgboost " + |
|
|
|
+ "mlflow run $repo " |
|
|
|
"-P data_path=$data_path " + |
|
|
|
+ "-P algorithm=xgboost " |
|
|
|
"-P params=\"n_estimators=100\" " + |
|
|
|
+ "-P data_path=$data_path " |
|
|
|
"-P search_params=\"\" " + |
|
|
|
+ "-P params=\"n_estimators=100\" " |
|
|
|
"-P model_name=\"BasicAlgorithm\" " + |
|
|
|
+ "-P search_params=\"\" " |
|
|
|
"--experiment-name=\"BasicAlgorithm\" " + |
|
|
|
+ "-P model_name=\"BasicAlgorithm\" " |
|
|
|
"--version=main "); |
|
|
|
+ "--experiment-name=\"BasicAlgorithm\""); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
@Test |
|
|
|
public void testInitAutoMLTask() { |
|
|
|
public void testInitAutoMLTask() { |
|
|
|
MlflowTask mlflowTask = initTask(createAutoMLParameters()); |
|
|
|
MlflowTask mlflowTask = initTask(createAutoMLParameters()); |
|
|
|
Assert.assertEquals(mlflowTask.buildCommand(), |
|
|
|
Assert.assertEquals(mlflowTask.buildCommand(), |
|
|
|
"export MLFLOW_TRACKING_URI=http://127.0.0.1:5000\n" + |
|
|
|
"export MLFLOW_TRACKING_URI=http://127.0.0.1:5000\n" |
|
|
|
"data_path=/data/iris.csv\n" + |
|
|
|
+ "data_path=/data/iris.csv\n" |
|
|
|
"repo=https://github.com/apache/dolphinscheduler-mlflow#Project-AutoML\n" + |
|
|
|
+ "repo=dolphinscheduler-mlflow#Project-AutoML\n" |
|
|
|
"mlflow run $repo " + |
|
|
|
+ "git clone https://github.com/apache/dolphinscheduler-mlflow dolphinscheduler-mlflow\n" |
|
|
|
"-P tool=autosklearn " + |
|
|
|
+ "mlflow run $repo " |
|
|
|
"-P data_path=$data_path " + |
|
|
|
+ "-P tool=autosklearn " |
|
|
|
"-P params=\"time_left_for_this_task=30\" " + |
|
|
|
+ "-P data_path=$data_path " |
|
|
|
"-P model_name=\"AutoML\" " + |
|
|
|
+ "-P params=\"time_left_for_this_task=30\" " |
|
|
|
"--experiment-name=\"AutoML\" " + |
|
|
|
+ "-P model_name=\"AutoML\" " |
|
|
|
"--version=main "); |
|
|
|
+ "--experiment-name=\"AutoML\""); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
@Test |
|
|
|
public void testInitCustomProjectTask() { |
|
|
|
public void testInitCustomProjectTask() { |
|
|
|
MlflowTask mlflowTask = initTask(createCustomProjectParameters()); |
|
|
|
MlflowTask mlflowTask = initTask(createCustomProjectParameters()); |
|
|
|
Assert.assertEquals(mlflowTask.buildCommand(), |
|
|
|
Assert.assertEquals(mlflowTask.buildCommand(), |
|
|
|
"export MLFLOW_TRACKING_URI=http://127.0.0.1:5000\n" + |
|
|
|
"export MLFLOW_TRACKING_URI=http://127.0.0.1:5000\n" |
|
|
|
"repo=https://github.com/mlflow/mlflow#examples/xgboost/xgboost_native\n" + |
|
|
|
+ "repo=https://github.com/mlflow/mlflow#examples/xgboost/xgboost_native\n" |
|
|
|
"mlflow run $repo " + |
|
|
|
+ "mlflow run $repo " |
|
|
|
"-P learning_rate=0.2 " + |
|
|
|
+ "-P learning_rate=0.2 " |
|
|
|
"-P colsample_bytree=0.8 " + |
|
|
|
+ "-P colsample_bytree=0.8 " |
|
|
|
"-P subsample=0.9 " + |
|
|
|
+ "-P subsample=0.9 " |
|
|
|
"--experiment-name=\"custom_project\" " + |
|
|
|
+ "--experiment-name=\"custom_project\" " |
|
|
|
"--version=\"master\" "); |
|
|
|
+ "--version=\"master\" "); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
@Test |
|
|
|
public void testModelsDeployMlflow() { |
|
|
|
public void testModelsDeployMlflow() { |
|
|
|
MlflowTask mlflowTask = initTask(createModelDeplyMlflowParameters()); |
|
|
|
MlflowTask mlflowTask = initTask(createModelDeplyMlflowParameters()); |
|
|
|
Assert.assertEquals(mlflowTask.buildCommand(), |
|
|
|
Assert.assertEquals(mlflowTask.buildCommand(), |
|
|
|
"export MLFLOW_TRACKING_URI=http://127.0.0.1:5000\n" + |
|
|
|
"export MLFLOW_TRACKING_URI=http://127.0.0.1:5000\n" |
|
|
|
"mlflow models serve -m models:/model/1 --port 7000 -h 0.0.0.0"); |
|
|
|
+ "mlflow models serve -m models:/model/1 --port 7000 -h 0.0.0.0"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
@Test |
|
|
|
public void testModelsDeployDocker() { |
|
|
|
public void testModelsDeployDocker() { |
|
|
|
MlflowTask mlflowTask = initTask(createModelDeplyDockerParameters()); |
|
|
|
MlflowTask mlflowTask = initTask(createModelDeplyDockerParameters()); |
|
|
|
Assert.assertEquals(mlflowTask.buildCommand(), |
|
|
|
Assert.assertEquals(mlflowTask.buildCommand(), |
|
|
|
"export MLFLOW_TRACKING_URI=http://127.0.0.1:5000\n" + |
|
|
|
"export MLFLOW_TRACKING_URI=http://127.0.0.1:5000\n" |
|
|
|
"mlflow models build-docker -m models:/model/1 -n mlflow/model:1 --enable-mlserver\n" + |
|
|
|
+ "mlflow models build-docker -m models:/model/1 -n mlflow/model:1 --enable-mlserver\n" |
|
|
|
"docker rm -f ds-mlflow-model-1\n" + |
|
|
|
+ "docker rm -f ds-mlflow-model-1\n" |
|
|
|
"docker run -d --name=ds-mlflow-model-1 -p=7000:8080 " + |
|
|
|
+ "docker run -d --name=ds-mlflow-model-1 -p=7000:8080 " |
|
|
|
"--health-cmd \"curl --fail http://127.0.0.1:8080/ping || exit 1\" --health-interval 5s --health-retries 20 " + |
|
|
|
+ "--health-cmd \"curl --fail http://127.0.0.1:8080/ping || exit 1\" --health-interval 5s --health-retries 20 " |
|
|
|
"mlflow/model:1"); |
|
|
|
+ "mlflow/model:1"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
@Test |
|
|
|
public void testModelsDeployDockerCompose() throws Exception{ |
|
|
|
public void testModelsDeployDockerCompose() throws Exception { |
|
|
|
MlflowTask mlflowTask = initTask(createModelDeplyDockerComposeParameters()); |
|
|
|
MlflowTask mlflowTask = initTask(createModelDeplyDockerComposeParameters()); |
|
|
|
Assert.assertEquals(mlflowTask.buildCommand(), |
|
|
|
Assert.assertEquals(mlflowTask.buildCommand(), |
|
|
|
"export MLFLOW_TRACKING_URI=http://127.0.0.1:5000\n" + |
|
|
|
"export MLFLOW_TRACKING_URI=http://127.0.0.1:5000\n" |
|
|
|
"cp " + mlflowTask.getTemplatePath(MlflowConstants.TEMPLATE_DOCKER_COMPOSE) + |
|
|
|
+ "cp " |
|
|
|
" /tmp/dolphinscheduler_test\n" + |
|
|
|
+ mlflowTask.getTemplatePath(MlflowConstants.TEMPLATE_DOCKER_COMPOSE) |
|
|
|
"mlflow models build-docker -m models:/model/1 -n mlflow/model:1 --enable-mlserver\n" + |
|
|
|
+ " /tmp/dolphinscheduler_test\n" |
|
|
|
"docker rm -f ds-mlflow-model-1\n" + |
|
|
|
+ "mlflow models build-docker -m models:/model/1 -n mlflow/model:1 --enable-mlserver\n" |
|
|
|
"export DS_TASK_MLFLOW_IMAGE_NAME=mlflow/model:1\n" + |
|
|
|
+ "docker rm -f ds-mlflow-model-1\n" |
|
|
|
"export DS_TASK_MLFLOW_CONTAINER_NAME=ds-mlflow-model-1\n" + |
|
|
|
+ "export DS_TASK_MLFLOW_IMAGE_NAME=mlflow/model:1\n" |
|
|
|
"export DS_TASK_MLFLOW_DEPLOY_PORT=7000\n" + |
|
|
|
+ "export DS_TASK_MLFLOW_CONTAINER_NAME=ds-mlflow-model-1\n" |
|
|
|
"export DS_TASK_MLFLOW_CPU_LIMIT=0.5\n" + |
|
|
|
+ "export DS_TASK_MLFLOW_DEPLOY_PORT=7000\n" |
|
|
|
"export DS_TASK_MLFLOW_MEMORY_LIMIT=200m\n" + |
|
|
|
+ "export DS_TASK_MLFLOW_CPU_LIMIT=0.5\n" |
|
|
|
"docker-compose up -d"); |
|
|
|
+ "export DS_TASK_MLFLOW_MEMORY_LIMIT=200m\n" |
|
|
|
|
|
|
|
+ "docker-compose up -d"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private MlflowTask initTask(MlflowParameters mlflowParameters) { |
|
|
|
private MlflowTask initTask(MlflowParameters mlflowParameters) { |
|
|
|