run.py 8.8 KB
Newer Older
T
tangwei 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

T
tangwei 已提交
15 16
import argparse
import os
T
tangwei 已提交
17
import subprocess
T
tangwei 已提交
18 19
import tempfile

T
tangwei 已提交
20
import yaml
T
tangwei 已提交
21

22 23 24
from paddlerec.core.factory import TrainerFactory
from paddlerec.core.utils import envs
from paddlerec.core.utils import util
T
tangwei 已提交
25

T
tangwei 已提交
26 27
engines = {}
device = ["CPU", "GPU"]
T
tangwei 已提交
28
clusters = ["SINGLE", "LOCAL_CLUSTER", "CLUSTER"]
T
tangwei 已提交
29 30 31
engine_choices = ["SINGLE", "LOCAL_CLUSTER", "CLUSTER",
                  "TDM_SINGLE", "TDM_LOCAL_CLUSTER", "TDM_CLUSTER"]
custom_model = ['TDM']
C
fix  
chengmo 已提交
32
model_name = ""
T
tangwei 已提交
33 34


T
tangwei 已提交
35
def engine_registry():
T
tangwei 已提交
36 37 38
    engines["TRANSPILER"] = {}
    engines["PSLIB"] = {}

T
tangwei 已提交
39 40 41
    engines["TRANSPILER"]["SINGLE"] = single_engine
    engines["TRANSPILER"]["LOCAL_CLUSTER"] = local_cluster_engine
    engines["TRANSPILER"]["CLUSTER"] = cluster_engine
T
tangwei 已提交
42

T
tangwei 已提交
43 44 45
    engines["PSLIB"]["SINGLE"] = local_mpi_engine
    engines["PSLIB"]["LOCAL_CLUSTER"] = local_mpi_engine
    engines["PSLIB"]["CLUSTER"] = cluster_mpi_engine
T
tangwei 已提交
46

T
tangwei 已提交
47 48 49 50 51 52 53 54 55 56 57 58

def get_inters_from_yaml(file, filter):
    with open(file, 'r') as rb:
        _envs = yaml.load(rb.read(), Loader=yaml.FullLoader)

    flattens = envs.flatten_environs(_envs)

    inters = {}
    for k, v in flattens.items():
        if k.startswith(filter):
            inters[k] = v
    return inters
T
tangwei 已提交
59 60


C
chengmo 已提交
61
def get_engine(args):
T
tangwei 已提交
62
    transpiler = get_transpiler()
T
tangwei 已提交
63 64
    run_extras = get_inters_from_yaml(args.model, "train.")

T
tangwei 已提交
65
    engine = run_extras.get("train.engine", "single")
T
tangwei 已提交
66
    engine = engine.upper()
C
chengmo 已提交
67

T
tangwei 已提交
68 69
    if engine not in engine_choices:
        raise ValueError("train.engin can not be chosen in {}".format(engine_choices))
T
tangwei 已提交
70

T
tangwei 已提交
71 72
    print("engines: \n{}".format(engines))

T
tangwei 已提交
73
    run_engine = engines[transpiler].get(engine, None)
T
tangwei 已提交
74

T
tangwei 已提交
75 76 77 78
    return run_engine


def get_transpiler():
T
tangwei 已提交
79 80 81 82 83 84
    FNULL = open(os.devnull, 'w')
    cmd = ["python", "-c",
           "import paddle.fluid as fluid; fleet_ptr = fluid.core.Fleet(); [fleet_ptr.copy_table_by_feasign(10, 10, [2020, 1010])];"]
    proc = subprocess.Popen(cmd, stdout=FNULL, stderr=FNULL, cwd=os.getcwd())
    ret = proc.wait()
    if ret == -11:
T
tangwei 已提交
85
        return "PSLIB"
T
tangwei 已提交
86
    else:
T
tangwei 已提交
87
        return "TRANSPILER"
T
tangwei 已提交
88 89


T
tangwei 已提交
90 91 92
def set_runtime_envs(cluster_envs, engine_yaml):
    if cluster_envs is None:
        cluster_envs = {}
T
tangwei 已提交
93

T
tangwei 已提交
94
    engine_extras = get_inters_from_yaml(engine_yaml, "train.trainer.")
95 96
    if "train.trainer.threads" in engine_extras and "CPU_NUM" in cluster_envs:
        cluster_envs["CPU_NUM"] = engine_extras["train.trainer.threads"]
T
tangwei 已提交
97

T
tangwei 已提交
98
    envs.set_runtime_environs(cluster_envs)
99
    envs.set_runtime_environs(engine_extras)
T
fix bug  
tangwei 已提交
100 101 102

    need_print = {}
    for k, v in os.environ.items():
T
tangwei 已提交
103
        if k.startswith("train.trainer."):
T
fix bug  
tangwei 已提交
104 105 106
            need_print[k] = v

    print(envs.pretty_print_envs(need_print, ("Runtime Envs", "Value")))
T
tangwei 已提交
107 108


C
chengmo 已提交
109 110 111 112
def get_trainer_prefix(args):
    if model_name in custom_model:
        return model_name.upper()
    return ""
T
tangwei 已提交
113

C
chengmo 已提交
114

C
chengmo 已提交
115 116
def single_engine(args):
    trainer = get_trainer_prefix(args) + "SingleTrainer"
C
chengmo 已提交
117
    single_envs = {}
C
chengmo 已提交
118
    single_envs["train.trainer.trainer"] = trainer
C
chengmo 已提交
119 120 121
    single_envs["train.trainer.threads"] = "2"
    single_envs["train.trainer.engine"] = "single"
    single_envs["train.trainer.platform"] = envs.get_platform()
C
chengmo 已提交
122
    print("use {} engine to run model: {}".format(trainer, args.model))
C
chengmo 已提交
123 124 125 126 127 128

    set_runtime_envs(single_envs, args.model)
    trainer = TrainerFactory.create(args.model)
    return trainer


T
tangwei 已提交
129
def cluster_engine(args):
T
tangwei 已提交
130 131 132 133 134 135
    def update_workspace(cluster_envs):
        workspace = cluster_envs.get("engine_workspace", None)
        if not workspace:
            return

        # is fleet inner models
136
        if workspace.startswith("paddlerec."):
T
tangwei 已提交
137
            fleet_package = envs.get_runtime_environ("PACKAGE_BASE")
138
            workspace_dir = workspace.split("paddlerec.")[1].replace(".", "/")
T
tangwei 已提交
139 140 141 142 143 144 145 146 147 148
            path = os.path.join(fleet_package, workspace_dir)
        else:
            path = workspace

        for name, value in cluster_envs.items():
            if isinstance(value, str):
                value = value.replace("{workspace}", path)
                cluster_envs[name] = value

    def master():
T
tangwei 已提交
149
        role = "MASTER"
150
        from paddlerec.core.engine.cluster.cluster import ClusterEngine
T
tangwei 已提交
151 152 153 154
        with open(args.backend, 'r') as rb:
            _envs = yaml.load(rb.read(), Loader=yaml.FullLoader)

        flattens = envs.flatten_environs(_envs, "_")
T
tangwei 已提交
155
        flattens["engine_role"] = role
T
tangwei 已提交
156
        flattens["engine_run_config"] = args.model
T
tangwei 已提交
157 158 159 160 161 162 163 164 165 166
        flattens["engine_temp_path"] = tempfile.mkdtemp()
        update_workspace(flattens)

        envs.set_runtime_environs(flattens)
        print(envs.pretty_print_envs(flattens, ("Submit Runtime Envs", "Value")))

        launch = ClusterEngine(None, args.model)
        return launch

    def worker():
T
tangwei 已提交
167
        role = "WORKER"
T
tangwei 已提交
168 169 170 171
        trainer = get_trainer_prefix(args) + "ClusterTrainer"
        cluster_envs = {}
        cluster_envs["train.trainer.trainer"] = trainer
        cluster_envs["train.trainer.engine"] = "cluster"
T
tangwei 已提交
172
        cluster_envs["train.trainer.threads"] = envs.get_runtime_environ("CPU_NUM")
T
tangwei 已提交
173
        cluster_envs["train.trainer.platform"] = envs.get_platform()
C
chengmo 已提交
174 175
        print("launch {} engine with cluster to with model: {}".format(
            trainer, args.model))
T
tangwei 已提交
176
        set_runtime_envs(cluster_envs, args.model)
T
tangwei 已提交
177

T
bug fix  
tangwei12 已提交
178 179
        trainer = TrainerFactory.create(args.model)
        return trainer
T
tangwei 已提交
180

T
tangwei 已提交
181 182 183
    role = os.getenv("PADDLE_PADDLEREC_ROLE", "MASTER")

    if role == "WORKER":
T
tangwei 已提交
184 185 186
        return worker()
    else:
        return master()
C
chengmo 已提交
187 188


T
tangwei 已提交
189
def cluster_mpi_engine(args):
T
tangwei 已提交
190 191
    print("launch cluster engine with cluster to run model: {}".format(args.model))

T
fix bug  
tangwei 已提交
192
    cluster_envs = {}
T
tangwei 已提交
193
    cluster_envs["train.trainer.trainer"] = "CtrCodingTrainer"
T
tangwei 已提交
194
    cluster_envs["train.trainer.platform"] = envs.get_platform()
T
tangwei 已提交
195

T
tangwei 已提交
196
    set_runtime_envs(cluster_envs, args.model)
T
tangwei 已提交
197

T
tangwei 已提交
198 199 200 201 202
    trainer = TrainerFactory.create(args.model)
    return trainer


def local_cluster_engine(args):
203
    from paddlerec.core.engine.local_cluster import LocalClusterEngine
C
chengmo 已提交
204

C
chengmo 已提交
205
    trainer = get_trainer_prefix(args) + "ClusterTrainer"
C
chengmo 已提交
206 207 208
    cluster_envs = {}
    cluster_envs["server_num"] = 1
    cluster_envs["worker_num"] = 1
C
chengmo 已提交
209
    cluster_envs["start_port"] = envs.find_free_port()
C
chengmo 已提交
210
    cluster_envs["log_dir"] = "logs"
C
chengmo 已提交
211
    cluster_envs["train.trainer.trainer"] = trainer
C
chengmo 已提交
212 213 214 215 216 217
    cluster_envs["train.trainer.strategy"] = "async"
    cluster_envs["train.trainer.threads"] = "2"
    cluster_envs["train.trainer.engine"] = "local_cluster"
    cluster_envs["train.trainer.platform"] = envs.get_platform()

    cluster_envs["CPU_NUM"] = "2"
C
chengmo 已提交
218
    print("launch {} engine with cluster to run model: {}".format(trainer, args.model))
C
chengmo 已提交
219 220 221 222 223 224

    set_runtime_envs(cluster_envs, args.model)
    launch = LocalClusterEngine(cluster_envs, args.model)
    return launch


T
tangwei 已提交
225
def local_mpi_engine(args):
T
tangwei 已提交
226
    print("launch cluster engine with cluster to run model: {}".format(args.model))
227
    from paddlerec.core.engine.local_mpi import LocalMPIEngine
T
tangwei 已提交
228

T
tangwei 已提交
229
    print("use 1X1 MPI ClusterTraining at localhost to run model: {}".format(args.model))
T
tangwei 已提交
230

T
tangwei 已提交
231 232 233
    mpi = util.run_which("mpirun")
    if not mpi:
        raise RuntimeError("can not find mpirun, please check environment")
T
fix bug  
tangwei 已提交
234 235
    cluster_envs = {}
    cluster_envs["mpirun"] = mpi
T
tangwei 已提交
236
    cluster_envs["train.trainer.trainer"] = "CtrCodingTrainer"
T
fix bug  
tangwei 已提交
237
    cluster_envs["log_dir"] = "logs"
T
tangwei 已提交
238
    cluster_envs["train.trainer.engine"] = "local_cluster"
T
tangwei 已提交
239 240

    cluster_envs["train.trainer.platform"] = envs.get_platform()
T
tangwei 已提交
241

T
tangwei 已提交
242
    set_runtime_envs(cluster_envs, args.model)
T
tangwei 已提交
243 244 245 246
    launch = LocalMPIEngine(cluster_envs, args.model)
    return launch


T
tangwei 已提交
247
def get_abs_model(model):
248
    if model.startswith("paddlerec."):
T
tangwei 已提交
249
        fleet_base = envs.get_runtime_environ("PACKAGE_BASE")
250
        workspace_dir = model.split("paddlerec.")[1].replace(".", "/")
T
tangwei 已提交
251 252 253 254 255 256 257 258
        path = os.path.join(fleet_base, workspace_dir, "config.yaml")
    else:
        if not os.path.isfile(model):
            raise IOError("model config: {} invalid".format(model))
        path = model
    return path


T
tangwei 已提交
259
if __name__ == "__main__":
260
    parser = argparse.ArgumentParser(description='paddle-rec run')
T
tangwei 已提交
261
    parser.add_argument("-m", "--model", type=str)
T
tangwei 已提交
262
    parser.add_argument("-b", "--backend", type=str, default=None)
T
tangwei 已提交
263

T
tangwei 已提交
264 265 266
    abs_dir = os.path.dirname(os.path.abspath(__file__))
    envs.set_runtime_environs({"PACKAGE_BASE": abs_dir})

T
tangwei 已提交
267
    args = parser.parse_args()
T
tangwei 已提交
268

C
fix  
chengmo 已提交
269
    model_name = args.model.split('.')[-1]
T
tangwei 已提交
270
    args.model = get_abs_model(args.model)
T
tangwei 已提交
271
    engine_registry()
T
tangwei 已提交
272

C
chengmo 已提交
273
    which_engine = get_engine(args)
T
tangwei 已提交
274 275
    engine = which_engine(args)
    engine.run()