华为云用户手册
-
修改标注 当数据完成标注后,您还可以进入已标注页签,对已标注的数据进行修改。 基于图片修改 在数据标注页面,单击“已标注”页签,然后在图片列表中选中待修改的图片(选择一个或多个)。在右侧标签信息区域中对图片信息进行修改。 添加标签:在“标签名”右侧文本框中,选择已有标签或输入新的标签名,然后单击,为选中图片增加标签。 修改标签:在“选中文件标签”区域中,单击操作列的编辑图标,然后在文本框中输入正确的标签名,然后单击确定图标完成修改。 图5 编辑标签 删除标签:在“选中文件标签”区域中,单击操作列的删除该标签。 基于标签修改 在数据标注概览页,单击右侧的“标签管理”,即可显示全部标签的信息。 图6 全部标签的信息 修改标签:在需要修改的标签的“操作”列,单击“修改”,输入修改后的标签,单击“确定”即可。 删除标签:选择对应的标签,单击操作列的“删除”,在弹出的“删除标签”对话框中单击“确定”即可删除对应的标签。 删除后无法再恢复,请谨慎操作。
-
数据发布 ModelArts训练管理模块支持通过ModelArts数据集或者OBS目录中的文件创建训练作业。如果选择通过数据集作为训练作业的数据源,则需要指定数据集及特定的版本。因此,用户需要为准备好的数据发布一个版本,具体操作参考发布ModelArts数据集中的数据版本。 为了便于后期的模型构建和开发,对同一数据源来说,将其不同时间对数据的处理和标注按照版本来进行区分,按照需求选择指定的版本使用。 图11 创建训练作业的数据来源
-
数据分析 数据集创建完成后,可以基于图片各项特征,如模糊度、亮度等进行分析,帮助用户更好的分析数据集的数据质量,判断数据集是否满足自己的算法和模型要求。 创建特征分析任务 在执行特征分析前,需先发布一个数据集版本。在“数据集概览”页单击右上角的“发布”,为数据集发布一个新版本。 版本发布完成后,进入数据集概览页。选择“数据特征”页签,单击“特征分析”,在弹窗中选择刚才发布的数据集版本,并单击“确定”,启动特征分析任务。 图3 启动特征分析 查看任务进度 任务执行过程中,可以单击“任务历史”,查看任务进度。当任务状态变为“成功”时,表示任务执行完成。 图4 特征分析任务进度 查看特征分析结果 特征分析任务执行完成后,可以在“数据特征”页签下,选择“数据集版本”、“类型”和“数据特征指标”,页面将自动呈现您选择对应版本及其指标数据,您可以根据呈现的图表了解数据分布情况,帮助您更好的理解您的数据。 “版本选择”:根据实际情况选择已执行过特征任务的版本,可以选多个进行对比,也可以只选择一个。 “类型”:根据需要分析的类型选择。支持“all”、“train”、“eval”和“inference”。分别表示所有、训练、评估和推理类型。 “数据特征指标”:选择您需要展示的指标。详细指标解释,可参见特征分析指标列表。 图5 查看特征分析结果 在特征分析结果中,例如图片亮度指标,数据分布中,分布不均匀,缺少某一种亮度的图片,而此指标对模型训练非常关键。此时可选择增加对应亮度的图片,让数据更均衡,为后续模型构建做准备。
-
数据标注 人工标注 在“未标注”页签图片列表中,单击图片,自动跳转到标注页面。 在标注页面的工具栏中选择合适的标注工具,本示例使用矩形框进行标注。 图6 标注工具 使用标注工具选中目标区域,在弹出的标签文本框中,直接输入新的标签名。如果已存在标签,从下拉列表中选择已有的标签。单击“添加”完成标注。 图7 添加物体检测标签 单击页面上方“返回数据标注预览”查看标注信息,在弹框中单击“确定”保存当前标注并离开标注页面。选中的图片被自动移动至“已标注”页签,且在“未标注”和“全部”页签中,标签的信息也将随着标注步骤进行更新,如增加的标签名称、标签对应的图片数量。 智能标注 通过人工标注完成少量数据标注后,可以通过智能标注对剩下的数据进行自动标注,提高标注的效率。 在数据集详情页面,单击右上角“启动智能标注”。 在“启动智能标注”窗口中,填写如下参数,然后单击“提交”。 智能标注类型:主动学习 算法类型:快速型 其他参数采用默认值。 图8 启动智能标注任务 查看智能标注任务进度 智能标注任务启动后,可以在“待确认”页签下查看智能标注任务进度。当任务完成后,即可在“待确认”页签下查看自动标注好的数据。 图9 查看智能标注任务进度 确认智能标注结果 在智能标注任务完成后,在“待确认”页签下,单击具体图片进入标注详情页面,可以查看或修改智能标注的结果。 如果智能标注的数据无误,可单击右侧的“确认标注”完成标注,如果标注信息有误,可直接删除错误标注框,然后重新标注,以纠正标注信息。针对物体检测任务,需一张一张确认。确保所有图片已完成确认,然后执行下一步操作。 图10 确认智能标注结果
-
数据导出 ModelArts训练管理模块支持通过ModelArts数据集或者OBS目录中的文件创建训练作业。如果选择通过OBS目录的方式创建训练作业,用户需要将数据集中准备好的数据导出到OBS中。 导出数据到OBS 在数据集详情页面中,选中需要导出的数据或筛选出需要导出的数据,然后单击右上角“导出”。 导出方式选择“OBS”,填写相关信息,然后单击“确定”,开始执行导出操作。 “保存路径”:即导出数据存储的路径。建议不要将数据存储至当前数据集所在的输入路径或输出路径。 图12 导出至OBS 数据导出成功后,您可以前往您设置的保存路径,查看到存储的数据。 查看任务历史 当您导出数据后,可以通过任务历史查看导出任务明细。 在数据集详情页面中,单击右上角“任务历史 ”。 在弹出的“任务历史”对话框中,可以查看该数据集之前的导出任务历史。包括“任务ID”、“创建时间”、“导出方式”、“导出路径”、“导出样本总数”和“导出状态”。 图13 导出任务历史
-
子账号启动其他用户的SSH实例 子账号可以看到所有用户的Notebook实例后,如果要通过SSH方式远程连接其他用户的Notebook实例,需要将SSH密钥对更新成自己的,否则会报错ModelArts.6786。更新密钥对具体操作请参见修改Notebook SSH远程连接配置。具体的错误信息提示:ModelArts.6789: 在E CS 密钥对管理中找不到指定的ssh密钥对xxx,请更新密钥对并重试。
-
示例:基于 自定义镜像 创建训练作业 指定命令行options参数提交训练作业 ma-cli ma-job submit --image-url atelier/pytorch_1_8:pytorch_1.8.0-cuda_10.2-py_3.7-ubuntu_18.04-x86_64-20220926104358-041ba2e \ --code-dir obs://your-bucket/mnist/code/ \ --user-command "export LD_LIBRARY_PATH=/usr/local/cuda/compat:$LD_LIBRARY_PATH && cd /home/ma-user/modelarts/user-job-dir/code && /home/ma-user/anaconda3/envs/PyTorch-1.8/bin/python main.py" \ --data-url obs://your-bucket/mnist/dataset/MNIST/ \ --log-url obs://your-bucket/mnist/logs/ \ --train-instance-type modelarts.vm.cpu.8u \ --train-instance-count 1 \ -q 使用自定义镜像的train.yaml样例: # .ma/train.yaml样例(自定义镜像) image-url: atelier/pytorch_1_8:pytorch_1.8.0-cuda_10.2-py_3.7-ubuntu_18.04-x86_64-20220926104358-041ba2e user-command: export LD_LIBRARY_PATH=/usr/local/cuda/compat:$LD_LIBRARY_PATH && cd /home/ma-user/modelarts/user-job-dir/code && /home/ma-user/anaconda3/envs/PyTorch-1.8/bin/python main.py train-instance-type: modelarts.vm.cpu.8u train-instance-count: 1 data-url: obs://your-bucket/mnist/dataset/MNIST/ code-dir: obs://your-bucket/mnist/code/ log-url: obs://your-bucket/mnist/logs/ ##[Optional] Uncomment to set uid when use custom image mode uid: 1000 ##[Optional] Uncomment to upload output file/dir to OBS from training platform output: - name: output_dir obs_path: obs://your-bucket/mnist/output1/ ##[Optional] Uncomment to download input file/dir from OBS to training platform input: - name: data_url obs_path: obs://your-bucket/mnist/dataset/MNIST/ ##[Optional] Uncomment pass hyperparameters parameters: - epoch: 10 - learning_rate: 0.01 - pretrained: ##[Optional] Uncomment to use dedicated pool pool_id: pool_xxxx ##[Optional] Uncomment to use volumes attached to the training job volumes: - efs: local_path: /xx/yy/zz read_only: false nfs_server_path: xxx.xxx.xxx.xxx:/
-
示例:基于ModelArts预置镜像提交训练作业 指定命令行options参数提交训练作业 ma-cli ma-job submit --code-dir obs://your-bucket/mnist/code/ \ --boot-file main.py \ --framework-type PyTorch \ --working-dir /home/ma-user/modelarts/user-job-dir/code \ --framework-version pytorch_1.8.0-cuda_10.2-py_3.7-ubuntu_18.04-x86_64 \ --data-url obs://your-bucket/mnist/dataset/MNIST/ \ --log-url obs://your-bucket/mnist/logs/ \ --train-instance-type modelarts.vm.cpu.8u \ --train-instance-count 1 \ -q 使用预置镜像的train.yaml样例: # .ma/train.yaml样例(预置镜像) # pool_id: pool_xxxx train-instance-type: modelarts.vm.cpu.8u train-instance-count: 1 data-url: obs://your-bucket/mnist/dataset/MNIST/ code-dir: obs://your-bucket/mnist/code/ working-dir: /home/ma-user/modelarts/user-job-dir/code framework-type: PyTorch framework-version: pytorch_1.8.0-cuda_10.2-py_3.7-ubuntu_18.04-x86_64 boot-file: main.py log-url: obs://your-bucket/mnist/logs/ ##[Optional] Uncomment to set uid when use custom image mode uid: 1000 ##[Optional] Uncomment to upload output file/dir to OBS from training platform output: - name: output_dir obs_path: obs://your-bucket/mnist/output1/ ##[Optional] Uncomment to download input file/dir from OBS to training platform input: - name: data_url obs_path: obs://your-bucket/mnist/dataset/MNIST/ ##[Optional] Uncomment pass hyperparameters parameters: - epoch: 10 - learning_rate: 0.01 - pretrained: ##[Optional] Uncomment to use dedicated pool pool_id: pool_xxxx ##[Optional] Uncomment to use volumes attached to the training job volumes: - efs: local_path: /xx/yy/zz read_only: false nfs_server_path: xxx.xxx.xxx.xxx:/
-
使用ma-cli ma-job get-log命令查询ModelArts训练作业日志 执行ma-cli ma-job get-log命令查询ModelArts训练作业日志。 $ ma-cli ma-job get-log -h Usage: ma-cli ma-job get-log [OPTIONS] Get job log details. Example: # Get job log by job id ma-cli ma-job get-log --job-id ${job_id} Options: -i, --job-id TEXT Get training job details by job id. [required] -t, --task-id TEXT Get training job details by task id (default "worker-0"). -C, --config-file TEXT Configure file path for authorization. -D, --debug Debug Mode. Shows full stack trace when error occurs. -P, --profile TEXT CLI connection profile to use. The default profile is "DEFAULT". -h, -H, --help Show this message and exit. 参数名 参数类型 是否必选 参数说明 -i / --job-id String 是 查询指定训练作业ID的任务日志。 -t / --task-id String 否 查询指定task的日志,默认是work-0。 示例:查询指定训练作业ID的作业日志。 ma-cli ma-job get-log --job-id b63e90baxxx
-
使用ma-cli ma-job get-flavor命令查询ModelArts训练资源规格 执行ma-cli ma-job get-flavor命令查询ModelArts训练的资源规格。 $ ma-cli ma-job get-flavor -h Usage: ma-cli ma-job get-flavor [OPTIONS] Get job flavor info. Example: # Get training job flavors ma-cli ma-job get-flavor Options: -t, --flavor-type [CPU|GPU|Ascend] Type of training job flavor. -v, --verbose Show detailed information about training flavors. -C, --config-file TEXT Configure file path for authorization. -D, --debug Debug Mode. Shows full stack trace when error occurs. -P, --profile TEXT CLI connection profile to use. The default profile is "DEFAULT". -H, -h, --help Show this message and exit. 表5 参数说明 参数名 参数类型 是否必选 参数说明 -t / --flavor-type String 否 资源规格类型,如果不指定默认返回所有的资源规格。 -v / --verbose Bool 否 显示详细的信息开关,默认关闭。 示例:查看训练作业的资源规格及类型。 ma-cli ma-job get-flavor
-
使用ma-cli ma-job stop命令停止ModelArts训练作业 执行ma-cli ma-job stop命令,可停止指定作业id的训练作业。 $ ma-cli ma-job stop -h Usage: ma-cli ma-job stop [OPTIONS] Stop training job by job id. Example: Stop training job by job id ma-cli ma-job stop --job-id ${job_id} Options: -i, --job-id TEXT Get training job event by job id. [required] -y, --yes Confirm stop operation. -C, --config-file TEXT Configure file path for authorization. -D, --debug Debug Mode. Shows full stack trace when error occurs. -P, --profile TEXT CLI connection profile to use. The default profile is "DEFAULT". -H, -h, --help Show this message and exit. 表6 参数说明 参数名 参数类型 是否必选 参数说明 -i / --job-id String 是 ModelArts训练作业ID。 -y / --yes Bool 否 强制关闭指定训练作业。 示例:停止运行中的训练作业。 ma-cli ma-job stop --job-id efd3e2f8xxx
-
使用ma-cli ma-job get-event命令查询ModelArts训练作业事件 执行ma-cli ma-job get-event命令查看ModelArts训练作业事件。 $ ma-cli ma-job get-event -h Usage: ma-cli ma-job get-event [OPTIONS] Get job running event. Example: # Get training job running event ma-cli ma-job get-event --job-id ${job_id} Options: -i, --job-id TEXT Get training job event by job id. [required] -C, --config-file TEXT Configure file path for authorization. -D, --debug Debug Mode. Shows full stack trace when error occurs. -P, --profile TEXT CLI connection profile to use. The default profile is "DEFAULT". -H, -h, --help Show this message and exit. 参数名 参数类型 是否必选 参数说明 -i / --job-id String 是 查询指定训练作业ID的事件。 示例:查看指定ID的训练作业的事件详情等。 ma-cli ma-job get-event --job-id b63e90baxxx
-
使用ma-cli ma-job get-engine命令查询ModelArts训练AI引擎 执行ma-cli ma-job get-engine命令查询ModelArts训练使用的AI引擎。 $ ma-cli ma-job get-engine -h Usage: ma-cli ma-job get-engine [OPTIONS] Get job engine info. Example: # Get training job engines ma-cli ma-job get-engine Options: -v, --verbose Show detailed information about training engines. -C, --config-file TEXT Configure file path for authorization. -D, --debug Debug Mode. Shows full stack trace when error occurs. -P, --profile TEXT CLI connection profile to use. The default profile is "DEFAULT". -H, -h, --help Show this message and exit. 表4 参数说明 参数名 参数类型 是否必选 参数说明 -v / --verbose Bool 否 显示详细的信息开关,默认关闭。 示例:查看训练作业的AI引擎。 ma-cli ma-job get-engine
-
使用ma-cli ma-job submit命令提交ModelArts训练作业 执行ma-cli ma-job submit命令提交ModelArts训练作业。 ma-cli ma-job submit命令需要指定一个位置参数YAML_FILE表示作业的配置文件路径,如果不指定该参数,则表示配置文件为空。配置文件是一个YAML格式的文件,里面的参数就是命令的option参数。此外,如果用户在命令行中同时指定YAML_FILE配置文件和option参数,命令行中指定的option参数的值将会覆盖配置文件相同的值。 $ma-cli ma-job submit -h Usage: ma-cli ma-job submit [OPTIONS] [YAML_FILE]... Submit training job. Example: ma-cli ma-job submit --code-dir obs://your_bucket/code/ --boot-file main.py --framework-type PyTorch --working-dir /home/ma-user/modelarts/user-job-dir/code --framework-version pytorch_1.8.0-cuda_10.2-py_3.7-ubuntu_18.04-x86_64 --data-url obs://your_bucket/dataset/ --log-url obs://your_bucket/logs/ --train-instance-type modelarts.vm.cpu.8u --train-instance-count 1 Options: --name TEXT Job name. --description TEXT Job description. --image-url TEXT Full swr custom image path. --uid TEXT Uid for custom image (default: 1000). --working-dir TEXT ModelArts training job working directory. --local-code-dir TEXT ModelArts training job local code directory. --user-command TEXT Execution command for custom image. --pool-id TEXT Dedicated pool id. --train-instance-type TEXT Train worker specification. --train-instance-count INTEGER Number of workers. --data-url TEXT OBS path for training data. --log-url TEXT OBS path for training log. --code-dir TEXT OBS path for source code. --output TEXT Training output parameter with OBS path. --input TEXT Training input parameter with OBS path. --env-variables TEXT Env variables for training job. --parameters TEXT Training job parameters (only keyword parameters are supported). --boot-file TEXT Training job boot file path behinds `code_dir`. --framework-type TEXT Training job framework type. --framework-version TEXT Training job framework version. --workspace-id TEXT The workspace where you submit training job(default "0") --policy [regular|economic|turbo|auto] Training job policy, default is regular. --volumes TEXT Information about the volumes attached to the training job. -q, --quiet Exit without waiting after submit successfully. -C, --config-file PATH Configure file path for authorization. -D, --debug Debug Mode. Shows full stack trace when error occurs. -P, --profile TEXT CLI connection profile to use. The default profile is "DEFAULT". -H, -h, --help Show this message and exit. 表3 参数说明 参数名 参数类型 是否必选 参数说明 YAML_FILE String 否 表示训练作业的配置文件,如果不传则表示配置文件为空。 --code-dir String 是 训练源代码的OBS路径。 --data-url String 是 训练数据的OBS路径。 --log-url String 是 存放训练生成日志的OBS路径。 --train-instance-count String 是 训练作业实例数,默认是1,表示单节点。 --boot-file String 否 当使用自定义镜像或自定义命令时可以省略,当使用预置命令提交训练作业时需要指定该参数。 --name String 否 训练作业名称。 --description String 否 训练作业描述信息。 --image-url String 否 自定义镜像SWR地址,遵循organization/image_name:tag --uid String 否 自定义镜像运行的UID,默认值1000。 --working-dir String 否 运行算法时所在的工作目录。 --local-code-dir String 否 算法的代码目录下载到训练容器内的本地路径。 --user-command String 否 自定义镜像执行命令。需为/home下的目录。 当code-dir以file://为前缀时,当前字段不生效。 --pool-id String 否 训练作业选择的资源池ID。可在ModelArts管理控制台,单击左侧“专属资源池”,在专属资源池列表中查看资源池ID。 --train-instance-type String 否 训练作业选择的资源规格。 --output String 否 训练的输出信息,指定后,训练作业将会把训练脚本中指定输出参数对应训练容器的输出目录上传到指定的OBS路径。如果需要指定多个参数,可以使用--output output1=obs://bucket/output1 --output output2=obs://bucket/output2 --input String 否 训练的输入信息,指定后,训练作业将会把对应OBS上的数据下载到训练容器,并将数据存储路径通过指定的参数传递给训练脚本。如果需要指定多个参数,可以使用--input data_path1=obs://bucket/data1 --input data_path2=obs://bucket/data2 --env-variables String 否 训练时传入的环境变量,如果需要指定多个参数,可以使用--env-variables ENV1=env1 --env-variables ENV2=env2 --parameters String 否 训练入参,可以通过--parameters "--epoch 0 --pretrained"指定多个参数。 --framework-type String 否 训练作业选择的引擎规格。 --framework-version String 否 训练作业选择的引擎版本。 -q / --quiet Bool 否 提交训练作业成功后直接退出,不再同步打印作业状态。 --workspace-id String 否 作业所处的工作空间,默认值为“0”。 --policy String 否 训练资源规格模式,可选值regular、economic、turbo、auto。 --volumes String 否 挂载EFS,如果需要指定多个参数,可以使用--volumes。 "local_path=/xx/yy/zz;read_only=false;nfs_server_path=xxx.xxx.xxx.xxx:/" -volumes "local_path=/xxx/yyy/zzz;read_only=false;nfs_server_path=xxx.xxx.xxx.xxx:/"
-
训练代码完整示例 训练代码示例中涉及的代码与您使用的AI引擎密切相关,以下案例以Tensorflow框架为例。案例中使用到的“mnist.npz”文件需要提前下载并上传至OBS桶中,训练输入为“mnist.npz”所在OBS路径。 以下训练代码样例中包含了保存模型代码。 import os import argparse import tensorflow as tf parser = argparse.ArgumentParser(description='train mnist') parser.add_argument('--data_url', type=str, default="./Data/mnist.npz", help='path where the dataset is saved') parser.add_argument('--train_url', type=str, default="./Model", help='path where the model is saved') args = parser.parse_args() mnist = tf.keras.datasets.mnist (x_train, y_train), (x_test, y_test) = mnist.load_data(args.data_url) x_train, x_test = x_train / 255.0, x_test / 255.0 model = tf.keras.models.Sequential([ tf.keras.layers.Flatten(input_shape=(28, 28)), tf.keras.layers.Dense(128, activation='relu'), tf.keras.layers.Dropout(0.2), tf.keras.layers.Dense(10) ]) loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True) model.compile(optimizer='adam', loss=loss_fn, metrics=['accuracy']) model.fit(x_train, y_train, epochs=5) model.save(os.path.join(args.train_url, 'model'))
-
解析输入路径参数、输出路径参数 运行在ModelArts Standard的训练作业会读取存储在OBS服务的数据,或者输出训练结果至OBS服务指定路径,输入和输出数据需要配置2个地方: 训练代码中需解析输入路径参数和输出路径参数。ModelArts Standard推荐以下方式实现参数解析。 1 2 3 4 5 6 7 8 9 10 import argparse # 创建解析 parser = argparse.ArgumentParser(description='train mnist') # 添加参数 parser.add_argument('--data_url', type=str, default="./Data/mnist.npz", help='path where the dataset is saved') parser.add_argument('--train_url', type=str, default="./Model", help='path where the model is saved') # 解析参数 args = parser.parse_args() 完成参数解析后,用户使用“data_url”、“train_url”代替算法中数据来源和数据输出所需的路径。 在创建训练作业时,填写输入路径和输出路径。 训练输入选择对应的OBS路径或者数据集路径;训练输出选择对应的OBS路径。
-
Step2 上传Summary数据 在开发环境中使用MindInsight可视化功能,需要用到Summary数据。 Summary数据可以直接传到开发环境的这个路径下/home/ma-user/work/,也可以放到OBS并行文件系统中。 Summary数据上传到Notebook路径/home/ma-user/work/下的方式,请参见上传数据至Notebook。 Summary数据如果是通过OBS并行文件系统挂载到Notebook中,请将模型训练时产生的Summary文件先上传到OBS并行文件系统,并确保OBS并行文件系统与ModelArts在同一区域。在Notebook中启动MindInsight时,Notebook会自动从挂载的OBS并行文件系统目录中读取Summary数据。
-
多节点分布式调测适配及代码示例 在DistributedDataParallel中,不同进程分别从原始数据中加载batch的数据,最终将各个进程的梯度进行平均作为最终梯度,由于样本量更大,因此计算出的梯度更加可靠,可以适当增大学习率。 以下对resnet18在cifar10数据集上的分类任务,给出了单机训练和分布式训练改造(DDP)的代码。直接执行代码为多节点分布式训练且支持CPU分布式和GPU分布式,将代码中的分布式改造点注释掉后即可进行单节点单卡训练。 训练代码中包含三部分入参,分别为训练基础参数、分布式参数和数据相关参数。其中分布式参数由平台自动入参,无需自行定义。数据相关参数中的custom_data表示是否使用自定义数据进行训练,该参数为“true”时使用基于torch自定义的随机数据进行训练和验证。 cifar10数据集 在Notebook中,无法直接使用默认版本的torchvision获取数据集,因此示例代码中提供了三种训练数据加载方式。 cifar-10数据集下载链接,单击“CIFAR-10 python version”。 尝试基于torchvision获取cifar10数据集。 基于数据链接下载数据并解压,放置在指定目录下,训练集和测试集的大小分别为(50000,3,32,32)和(10000,3,32,32)。 考虑到下载cifar10数据集较慢,基于torch生成类似cifar10的随机数据集,训练集和测试集的大小分别为(5000,3,32,32)和(1000,3,32,32),标签仍为10类,指定custom_data = 'true'后可直接进行训练任务,无需加载数据。 训练代码 以下代码中以“### 分布式改造,... ###”注释的代码即为多节点分布式训练需要适配的代码改造点。 不对示例代码进行任何修改,适配数据路径后即可在ModelArts上完成多节点分布式训练。 注释掉分布式代码改造点,即可完成单节点单卡训练。完整代码见分布式训练完整代码示例。 导入依赖包 import datetime import inspect import os import pickle import random import argparse import numpy as np import torch import torch.distributed as dist from torch import nn, optim from torch.utils.data import TensorDataset, DataLoader from torch.utils.data.distributed import DistributedSampler from sklearn.metrics import accuracy_score 定义加载数据的方法和随机数,由于加载数据部分代码较多,此处省略 def setup_seed(seed): torch.manual_seed(seed) torch.cuda.manual_seed_all(seed) np.random.seed(seed) random.seed(seed) torch.backends.cudnn.deterministic = True def get_data(path): pass 定义网络结构 class Block(nn.Module): def __init__(self, in_channels, out_channels, stride=1): super().__init__() self.residual_function = nn.Sequential( nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride, padding=1, bias=False), nn.BatchNorm2d(out_channels), nn.ReLU(inplace=True), nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=1, bias=False), nn.BatchNorm2d(out_channels) ) self.shortcut = nn.Sequential() if stride != 1 or in_channels != out_channels: self.shortcut = nn.Sequential( nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=stride, bias=False), nn.BatchNorm2d(out_channels) ) def forward(self, x): out = self.residual_function(x) + self.shortcut(x) return nn.ReLU(inplace=True)(out) class ResNet(nn.Module): def __init__(self, block, num_classes=10): super().__init__() self.conv1 = nn.Sequential( nn.Conv2d(3, 64, kernel_size=3, padding=1, bias=False), nn.BatchNorm2d(64), nn.ReLU(inplace=True)) self.conv2 = self.make_layer(block, 64, 64, 2, 1) self.conv3 = self.make_layer(block, 64, 128, 2, 2) self.conv4 = self.make_layer(block, 128, 256, 2, 2) self.conv5 = self.make_layer(block, 256, 512, 2, 2) self.avg_pool = nn.AdaptiveAvgPool2d((1, 1)) self.dense_layer = nn.Linear(512, num_classes) def make_layer(self, block, in_channels, out_channels, num_blocks, stride): strides = [stride] + [1] * (num_blocks - 1) layers = [] for stride in strides: layers.append(block(in_channels, out_channels, stride)) in_channels = out_channels return nn.Sequential(*layers) def forward(self, x): out = self.conv1(x) out = self.conv2(out) out = self.conv3(out) out = self.conv4(out) out = self.conv5(out) out = self.avg_pool(out) out = out.view(out.size(0), -1) out = self.dense_layer(out) return out 进行训练和验证 def main(): file_dir = os.path.dirname(inspect.getframeinfo(inspect.currentframe()).filename) seed = datetime.datetime.now().year setup_seed(seed) parser = argparse.ArgumentParser(description='Pytorch distribute training', formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('--enable_gpu', default='true') parser.add_argument('--lr', default='0.01', help='learning rate') parser.add_argument('--epochs', default='100', help='training iteration') parser.add_argument('--init_method', default=None, help='tcp_port') parser.add_argument('--rank', type=int, default=0, help='index of current task') parser.add_argument('--world_size', type=int, default=1, help='total number of tasks') parser.add_argument('--custom_data', default='false') parser.add_argument('--data_url', type=str, default=os.path.join(file_dir, 'input_dir')) parser.add_argument('--output_dir', type=str, default=os.path.join(file_dir, 'output_dir')) args, unknown = parser.parse_known_args() args.enable_gpu = args.enable_gpu == 'true' args.custom_data = args.custom_data == 'true' args.lr = float(args.lr) args.epochs = int(args.epochs) if args.custom_data: print('[warning] you are training on custom random dataset, ' 'validation accuracy may range from 0.4 to 0.6.') ### 分布式改造,DDP初始化进程,其中init_method, rank和world_size参数均由平台自动入参 ### dist.init_process_group(init_method=args.init_method, backend="nccl", world_size=args.world_size, rank=args.rank) ### 分布式改造,DDP初始化进程,其中init_method, rank和world_size参数均由平台自动入参 ### tr_set, val_set = get_data(args.data_url, custom_data=args.custom_data) batch_per_gpu = 128 gpus_per_node = torch.cuda.device_count() if args.enable_gpu else 1 batch = batch_per_gpu * gpus_per_node tr_loader = DataLoader(tr_set, batch_size=batch, shuffle=False) ### 分布式改造,构建DDP分布式数据sampler,确保不同进程加载到不同的数据 ### tr_sampler = DistributedSampler(tr_set, num_replicas=args.world_size, rank=args.rank) tr_loader = DataLoader(tr_set, batch_size=batch, sampler=tr_sampler, shuffle=False, drop_last=True) ### 分布式改造,构建DDP分布式数据sampler,确保不同进程加载到不同的数据 ### val_loader = DataLoader(val_set, batch_size=batch, shuffle=False) lr = args.lr * gpus_per_node max_epoch = args.epochs model = ResNet(Block).cuda() if args.enable_gpu else ResNet(Block) ### 分布式改造,构建DDP分布式模型 ### model = nn.parallel.DistributedDataParallel(model) ### 分布式改造,构建DDP分布式模型 ### optimizer = optim.Adam(model.parameters(), lr=lr) loss_func = torch.nn.CrossEntropyLoss() os.makedirs(args.output_dir, exist_ok=True) for epoch in range(1, max_epoch + 1): model.train() train_loss = 0 ### 分布式改造,DDP sampler, 基于当前的epoch为其设置随机数,避免加载到重复数据 ### tr_sampler.set_epoch(epoch) ### 分布式改造,DDP sampler, 基于当前的epoch为其设置随机数,避免加载到重复数据 ### for step, (tr_x, tr_y) in enumerate(tr_loader): if args.enable_gpu: tr_x, tr_y = tr_x.cuda(), tr_y.cuda() out = model(tr_x) loss = loss_func(out, tr_y) optimizer.zero_grad() loss.backward() optimizer.step() train_loss += loss.item() print('train | epoch: %d | loss: %.4f' % (epoch, train_loss / len(tr_loader))) val_loss = 0 pred_record = [] real_record = [] model.eval() with torch.no_grad(): for step, (val_x, val_y) in enumerate(val_loader): if args.enable_gpu: val_x, val_y = val_x.cuda(), val_y.cuda() out = model(val_x) pred_record += list(np.argmax(out.cpu().numpy(), axis=1)) real_record += list(val_y.cpu().numpy()) val_loss += loss_func(out, val_y).item() val_accu = accuracy_score(real_record, pred_record) print('val | epoch: %d | loss: %.4f | accuracy: %.4f' % (epoch, val_loss / len(val_loader), val_accu), '\n') if args.rank == 0: # save ckpt every epoch torch.save(model.state_dict(), os.path.join(args.output_dir, f'epoch_{epoch}.pth')) if __name__ == '__main__': main() 结果对比 分别以单机单卡和两节点16卡两种资源类型完成100epoch的cifar-10数据集训练,训练时长和测试集准确率如下。 表1 训练结果对比 资源类型 单机单卡 两节点16卡 耗时 60分钟 20分钟 准确率 80+ 80+
-
分布式训练完整代码示例 以下对resnet18在cifar10数据集上的分类任务,给出了分布式训练改造(DDP)的完整代码示例。 训练启动文件main.py内容如下(如果需要执行单机单卡训练任务,则将分布式改造的代码删除): import datetime import inspect import os import pickle import random import logging import argparse import numpy as np from sklearn.metrics import accuracy_score import torch from torch import nn, optim import torch.distributed as dist from torch.utils.data import TensorDataset, DataLoader from torch.utils.data.distributed import DistributedSampler file_dir = os.path.dirname(inspect.getframeinfo(inspect.currentframe()).filename) def load_pickle_data(path): with open(path, 'rb') as file: data = pickle.load(file, encoding='bytes') return data def _load_data(file_path): raw_data = load_pickle_data(file_path) labels = raw_data[b'labels'] data = raw_data[b'data'] filenames = raw_data[b'filenames'] data = data.reshape(10000, 3, 32, 32) / 255 return data, labels, filenames def load_cifar_data(root_path): train_root_path = os.path.join(root_path, 'cifar-10-batches-py/data_batch_') train_data_record = [] train_labels = [] train_filenames = [] for i in range(1, 6): train_file_path = train_root_path + str(i) data, labels, filenames = _load_data(train_file_path) train_data_record.append(data) train_labels += labels train_filenames += filenames train_data = np.concatenate(train_data_record, axis=0) train_labels = np.array(train_labels) val_file_path = os.path.join(root_path, 'cifar-10-batches-py/test_batch') val_data, val_labels, val_filenames = _load_data(val_file_path) val_labels = np.array(val_labels) tr_data = torch.from_numpy(train_data).float() tr_labels = torch.from_numpy(train_labels).long() val_data = torch.from_numpy(val_data).float() val_labels = torch.from_numpy(val_labels).long() return tr_data, tr_labels, val_data, val_labels def get_data(root_path, custom_data=False): if custom_data: train_samples, test_samples, img_size = 5000, 1000, 32 tr_label = [1] * int(train_samples / 2) + [0] * int(train_samples / 2) val_label = [1] * int(test_samples / 2) + [0] * int(test_samples / 2) random.seed(2021) random.shuffle(tr_label) random.shuffle(val_label) tr_data, tr_labels = torch.randn((train_samples, 3, img_size, img_size)).float(), torch.tensor(tr_label).long() val_data, val_labels = torch.randn((test_samples, 3, img_size, img_size)).float(), torch.tensor( val_label).long() tr_set = TensorDataset(tr_data, tr_labels) val_set = TensorDataset(val_data, val_labels) return tr_set, val_set elif os.path.exists(os.path.join(root_path, 'cifar-10-batches-py')): tr_data, tr_labels, val_data, val_labels = load_cifar_data(root_path) tr_set = TensorDataset(tr_data, tr_labels) val_set = TensorDataset(val_data, val_labels) return tr_set, val_set else: try: import torchvision from torchvision import transforms tr_set = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transforms) val_set = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transforms) return tr_set, val_set except Exception as e: raise Exception( f"{e}, you can download and unzip cifar-10 dataset manually, " "the data url is http://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz") class Block(nn.Module): def __init__(self, in_channels, out_channels, stride=1): super().__init__() self.residual_function = nn.Sequential( nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride, padding=1, bias=False), nn.BatchNorm2d(out_channels), nn.ReLU(inplace=True), nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=1, bias=False), nn.BatchNorm2d(out_channels) ) self.shortcut = nn.Sequential() if stride != 1 or in_channels != out_channels: self.shortcut = nn.Sequential( nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=stride, bias=False), nn.BatchNorm2d(out_channels) ) def forward(self, x): out = self.residual_function(x) + self.shortcut(x) return nn.ReLU(inplace=True)(out) class ResNet(nn.Module): def __init__(self, block, num_classes=10): super().__init__() self.conv1 = nn.Sequential( nn.Conv2d(3, 64, kernel_size=3, padding=1, bias=False), nn.BatchNorm2d(64), nn.ReLU(inplace=True)) self.conv2 = self.make_layer(block, 64, 64, 2, 1) self.conv3 = self.make_layer(block, 64, 128, 2, 2) self.conv4 = self.make_layer(block, 128, 256, 2, 2) self.conv5 = self.make_layer(block, 256, 512, 2, 2) self.avg_pool = nn.AdaptiveAvgPool2d((1, 1)) self.dense_layer = nn.Linear(512, num_classes) def make_layer(self, block, in_channels, out_channels, num_blocks, stride): strides = [stride] + [1] * (num_blocks - 1) layers = [] for stride in strides: layers.append(block(in_channels, out_channels, stride)) in_channels = out_channels return nn.Sequential(*layers) def forward(self, x): out = self.conv1(x) out = self.conv2(out) out = self.conv3(out) out = self.conv4(out) out = self.conv5(out) out = self.avg_pool(out) out = out.view(out.size(0), -1) out = self.dense_layer(out) return out def setup_seed(seed): torch.manual_seed(seed) torch.cuda.manual_seed_all(seed) np.random.seed(seed) random.seed(seed) torch.backends.cudnn.deterministic = True def obs_transfer(src_path, dst_path): import moxing as mox mox.file.copy_parallel(src_path, dst_path) logging.info(f"end copy data from {src_path} to {dst_path}") def main(): seed = datetime.datetime.now().year setup_seed(seed) parser = argparse.ArgumentParser(description='Pytorch distribute training', formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('--enable_gpu', default='true') parser.add_argument('--lr', default='0.01', help='learning rate') parser.add_argument('--epochs', default='100', help='training iteration') parser.add_argument('--init_method', default=None, help='tcp_port') parser.add_argument('--rank', type=int, default=0, help='index of current task') parser.add_argument('--world_size', type=int, default=1, help='total number of tasks') parser.add_argument('--custom_data', default='false') parser.add_argument('--data_url', type=str, default=os.path.join(file_dir, 'input_dir')) parser.add_argument('--output_dir', type=str, default=os.path.join(file_dir, 'output_dir')) args, unknown = parser.parse_known_args() args.enable_gpu = args.enable_gpu == 'true' args.custom_data = args.custom_data == 'true' args.lr = float(args.lr) args.epochs = int(args.epochs) if args.custom_data: logging.warning('you are training on custom random dataset, ' 'validation accuracy may range from 0.4 to 0.6.') ### 分布式改造,DDP初始化进程,其中init_method, rank和world_size参数均由平台自动入参 ### dist.init_process_group(init_method=args.init_method, backend="nccl", world_size=args.world_size, rank=args.rank) ### 分布式改造,DDP初始化进程,其中init_method, rank和world_size参数均由平台自动入参 ### tr_set, val_set = get_data(args.data_url, custom_data=args.custom_data) batch_per_gpu = 128 gpus_per_node = torch.cuda.device_count() if args.enable_gpu else 1 batch = batch_per_gpu * gpus_per_node tr_loader = DataLoader(tr_set, batch_size=batch, shuffle=False) ### 分布式改造,构建DDP分布式数据sampler,确保不同进程加载到不同的数据 ### tr_sampler = DistributedSampler(tr_set, num_replicas=args.world_size, rank=args.rank) tr_loader = DataLoader(tr_set, batch_size=batch, sampler=tr_sampler, shuffle=False, drop_last=True) ### 分布式改造,构建DDP分布式数据sampler,确保不同进程加载到不同的数据 ### val_loader = DataLoader(val_set, batch_size=batch, shuffle=False) lr = args.lr * gpus_per_node * args.world_size max_epoch = args.epochs model = ResNet(Block).cuda() if args.enable_gpu else ResNet(Block) ### 分布式改造,构建DDP分布式模型 ### model = nn.parallel.DistributedDataParallel(model) ### 分布式改造,构建DDP分布式模型 ### optimizer = optim.Adam(model.parameters(), lr=lr) loss_func = torch.nn.CrossEntropyLoss() os.makedirs(args.output_dir, exist_ok=True) for epoch in range(1, max_epoch + 1): model.train() train_loss = 0 ### 分布式改造,DDP sampler, 基于当前的epoch为其设置随机数,避免加载到重复数据 ### tr_sampler.set_epoch(epoch) ### 分布式改造,DDP sampler, 基于当前的epoch为其设置随机数,避免加载到重复数据 ### for step, (tr_x, tr_y) in enumerate(tr_loader): if args.enable_gpu: tr_x, tr_y = tr_x.cuda(), tr_y.cuda() out = model(tr_x) loss = loss_func(out, tr_y) optimizer.zero_grad() loss.backward() optimizer.step() train_loss += loss.item() print('train | epoch: %d | loss: %.4f' % (epoch, train_loss / len(tr_loader))) val_loss = 0 pred_record = [] real_record = [] model.eval() with torch.no_grad(): for step, (val_x, val_y) in enumerate(val_loader): if args.enable_gpu: val_x, val_y = val_x.cuda(), val_y.cuda() out = model(val_x) pred_record += list(np.argmax(out.cpu().numpy(), axis=1)) real_record += list(val_y.cpu().numpy()) val_loss += loss_func(out, val_y).item() val_accu = accuracy_score(real_record, pred_record) print('val | epoch: %d | loss: %.4f | accuracy: %.4f' % (epoch, val_loss / len(val_loader), val_accu), '\n') if args.rank == 0: # save ckpt every epoch torch.save(model.state_dict(), os.path.join(args.output_dir, f'epoch_{epoch}.pth')) if __name__ == '__main__': main() 常见问题 1、示例代码中如何使用不同的数据集? 上述代码如果使用cifar10数据集,则将数据集下载并解压后,上传至OBS桶中,文件目录结构如下: DDP |--- main.py |--- input_dir |------ cifar-10-batches-py |-------- data_batch_1 |-------- data_batch_2 |-------- ... 其中“DDP”为创建训练作业时的“代码目录”,“main.py”为上文代码示例(即创建训练作业时的“启动文件”),“cifar-10-batches-py”为解压后的数据集文件夹(放在input_dir文件夹下)。 如果使用自定义的随机数据,则将代码示例中的参数“custom_data”改为“true”,修改后内容如下: parser.add_argument('--custom_data', default='true') 然后直接运行代码示例“main.py”即可,创建训练作业的参数与上图相同。 2、为什么DDP可以不输入主节点ip? “parser.add_argument('--init_method', default=None, help='tcp_port')”中的init method参数值会包含主节点的ip和端口,由平台自动入参,不需要用户输入主节点的ip和端口。
-
训练流程简述 相比于DP,DDP能够启动多进程进行运算,从而大幅度提升计算资源的利用率。可以基于torch.distributed实现真正的分布式计算,具体的原理此处不再赘述。大致的流程如下: 初始化进程组。 创建分布式并行模型,每个进程都会有相同的模型和参数。 创建数据分发Sampler,使每个进程加载一个mini batch中不同部分的数据。 网络中相邻参数分桶,一般为神经网络模型中需要进行参数更新的每一层网络。 每个进程前向传播并各自计算梯度。 模型某一层的参数得到梯度后会马上进行通讯并进行梯度平均。 各GPU更新模型参数。 具体流程图如下: 图1 多机多卡数据并行训练
-
代码改造点 引入多进程启动机制:初始化进程 引入几个变量:tcp协议,rank进程序号,worldsize开启的进程数量 分发数据:DataLoader中多了一个Sampler参数,避免不同进程数据重复 模型分发:DistributedDataParallel(model) 模型保存:在序号为0的进程下保存模型 import torch class Net(torch.nn.Module): pass model = Net().cuda() ### DistributedDataParallel Begin ### model = torch.nn.parallel.DistributedDataParallel(Net().cuda()) ### DistributedDataParallel End ###
-
Notebook使用场景 ModelArts提供灵活开放的开发环境,您可以根据实际情况选择。 ModelArts提供了CodeLab功能,一方面,一键进入开发环境,同时预置了免费的算力规格,可直接 免费体验 Notebook功能;另一方面,针对AI Gallery社区发布的Notebook样例(.ipynb格式文件),可直接在CodeLab中打开,查看他人分享的样例代码,具体请参见使用CodeLab免费体验Notebook。 ModelArts提供了云化版本的Notebook,无需关注安装配置,即开即用,具体参见创建Notebook实例。 ModelArts Notebook支持以下几种使用方式,用于开发基于PyTorch、TensorFlow和MindSpore等引擎的AI模型。 支持通过JupyterLab工具在线打开Notebook,具体请参见通过JupyterLab在线使用Notebook实例进行AI开发。 支持本地IDE的方式开发模型,通过开启SSH连接,用户本地IDE可以远程连接到ModelArts的Notebook开发环境中,调试和运行代码。本地IDE方式不影响用户的编码习惯,并且可以方便快捷的使用云上的Notebook开发环境。 本地IDE当前支持VS Code、PyCharm、SSH工具。PyCharm和VS Code还分别有专门的插件PyCharm Toolkit、VS Code Toolkit,让远程连接操作更便捷。具体参见通过PyCharm远程使用Notebook实例、通过VS Code远程使用Notebook实例、通过SSH工具远程使用Notebook。 在AI开发过程中,如何将文件方便快速地上传到Notebook几乎是每个开发者都会遇到的问题。ModelArts提供了多种文件上传方式,在文件上传过程中,可以查看上传进度和速度。 将本地文件上传,请参考支持上传本地文件; GitHub的开源仓库的文件上传,请参考支持Clone GitHub开源仓库; 存放在OBS中的文件上传,请参考支持上传OBS文件; 类似开源数据集这样的远端文件上传,请参考支持上传远端文件; 在Notebook的使用中,可以快速查找实例,可以在同一个Notebook实例中切换镜像,方便用户灵活调整实例的AI引擎;可以切换节点运行规格,方便用户灵活调整规格资源;可以初期存储使用量较小时选择小存储,可以在创建完成后根据需要扩充EVS容量;使用动态挂载OBS将OBS对象存储模拟成本地文件系统;还可以在Notebook异常时查看实例的事件定位等,具体参见管理Notebook实例。 ModelArts CLI,集成在ModelArts开发环境Notebook中,用于连接ModelArts服务并在ModelArts资源上执行管理命令。ma-cli支持用户在ModelArts Notebook及线下虚拟机中与云端服务交互,使用ma-cli命令可以实现命令自动补全、鉴权、镜像构建、提交ModelArts训练作业、提交 DLI Spark作业、OBS数据复制等,具体参见ModelArts CLI命令参考。 ModelArts Notebook内置MoXing Framework模块,ModelArts mox.file提供了一套更为方便的访问OBS的API,允许用户通过一系列模仿操作本地文件系统的API来操作OBS文件。具体参见在Notebook中使用Moxing命令。 父主题: 使用Notebook进行AI开发调试
-
代码化参数插件的使用 代码参数化插件可以降低Notebook案例的复杂度,用户无需感知复杂的源码,按需调整参数快速进行案例复现、模型训练等。该插件可用于定制Notebook案例,适用于比赛、教学等场景。 仅对Code cell类型新增了Edit Form和Add Form功能,如果cell类型是Markdown或者Raw类型则不支持。如下图所示: 图16 查看Code cell 打开新的代码后,需先Add Form,再Edit Form。 图17 Code类型的cell右键选项 “Add Form”会将Code cell水平拆分为两种编辑区域,左侧为代码区域,右侧为表单区域。单击表单右侧的“Edit”可修改默认标题。 图18 两种编辑区域 “Edit Form”按钮有四个子选项,分别是“Add new form field”、“Hide code”、“Hide form”和“show all”四个按钮,下文介绍这四个选项的功能。 表5 “Edit Form”子选项介绍 “Edit Form”子选项 功能说明 Add new form field 支持新增“dropdown”、“input”和“slider”类型的表单。如图19所示。每新增一个字段,会分别在代码和表单区域中增加对应的变量,修改表单区域的值也会同时修改代码变量值。 说明: 创建dropdown类型的表单时,“ADD Item”至少创建2项。如图20所示。 表单字段类型为“dropdown”时,支持的变量类型为“raw”和“string”。 表单字段类型为“input”时,支持的变量类型有“boolean”、“date”、“integer”、“number” 、“raw”和“string”。 表单字段类型为“slider”时,支持输入滑动条的最小值、最大值和步长。 Hide code 隐藏代码区域。 Hide form 隐藏表单区域。 Show all 同时展示code和form区域。 图19 “dropdown”,“input”,“slider”的表单样式 图20 创建“dropdown”类型的表单 图21 删除表单
-
JupyterLab常用快捷键和插件栏 图13 JupyterLab常用快捷键和插件栏 表1 快捷键说明 快捷键 说明 快速打开Notebook、Terminal。或打开Launcher页面,可快速创建新的Notebook、Console或其他文件。 创建文件夹。 上传文件。 刷新文件目录。 Git插件,可连接此Notebook实例关联的Github代码库。 表2 插件栏常用插件说明 插件 说明 文件列表。单击此处,将展示此Notebook实例下的所有文件列表。 当前实例中正在运行的Terminal和Kernel。 Git插件,可以方便快捷的使用Github代码库。 属性检查器。 文档结构图。 图14 导航栏按钮 表3 导航栏按钮介绍 按钮 说明 File 新建、关闭、保存、重新加载、重命名、导出、打印Notebook等功能。 Edit 编辑ipynb文件中代码块的相关操作,包括撤销、重做、剪切、复制、粘贴、选择、移动、合并、清除、查找代码块等。 View 查看视图相关操作。 Run 运行代码块相关操作,例如:运行选中代码块、一键运行所有代码块等。 Kernel 中断、重启、关闭、改变Kernel相关操作。 Git Git插件相关操作,可以方便快捷的使用Github代码库。 Tabs 同时打开多个ipynb文件时,通过Tabs激活或选择文件。 Settings JupyterLab工具系统设置。 Help JupyterLab工具自带的帮助参考。 图15 ipynb文件菜单栏中的快捷键 表4 ipynb文件菜单栏中的快捷键 快捷键 说明 保存文件。 添加新代码块。 剪切选中的代码块。 复制选中的代码块。 粘贴选中的代码块。 执行选中的代码块。 终止kernel。 重启kernel。 重启kernel,然后重新运行当前Notebook的所有代码。 此处下拉框有4个选项,分别是: Code(写python代码),Markdown(写Markdown代码,通常用于注释),Raw(一个转换工具),-(不修改)。 查看代码历史版本。 git插件,图标显示灰色表示当前Region不支持。 当前的资源规格。 单击可以选择Kernel。 表示代码运行状态,变为实心圆时,表示代码在运行中。 分享到AI Gallery。
-
新建文件并打开Console Console的本质为Python终端,输入一条语句就会给出相应的输出,类似于Python原生的IDE。 进入JupyterLab主页后,可在“Console”区域下,选择适用的AI引擎,单击后将新建一个对应框架的Notebook文件。 由于每个Notebook实例选择的工作环境不同,其支持的AI框架也不同,下图仅为示例,请根据实际显示界面选择AI框架。 图6 选择AI引擎并新建一个Console 文件创建成功后,将直接呈现Console页面。 图7 新建文件(Console)
-
Standard使用场景介绍 ModelArts Standard是面向AI开发者的一站式开发平台,提供了简洁易用的管理控制台,包含自动学习、数据管理、开发环境、模型训练、模型管理、部署上线等端到端的AI开发工具链。 Standard的自动学习可以帮助用户零代码构建AI模型。自动学习功能根据标注数据自动设计模型、自动调参、自动训练、自动压缩和部署模型。开发者无需专业的开发基础和编码能力,只需上传数据,通过自动学习界面引导和简单操作即可完成模型训练和部署。具体请参见自动学习简介。 Standard的Workflow是一套低代码的AI开发流水线工具,覆盖数据标注、数据处理、模型开发、训练、模型评估、部署上线等步骤,提供可视化的工作流运行方式。具体请参见什么是Workflow。 Standard的开发环境Notebook提供了云上JupyterLab环境和本地IDE插件,方便用户编写训练推理代码,并使用云上资源进行代码调试。具体请参见Notebook使用场景。 Standard的模型训练功能提供了界面化的训练调试环境和生产环境,用户可以使用自己的数据和算法,利用Standard提供的计算资源开展模型训练。具体请参见使用ModelArts Standard训练模型。 Standard的推理部署功能提供了界面化的推理部署生产环境,AI模型开发完成后,在Standard中可以纳管AI模型并快速部署为推理服务,您可以进行在线推理预测,也可以通过调用API把AI推理能力集成到自己的IT平台。具体请参见推理部署使用场景。
-
Standard使用流程说明 ModelArts Standard平台提供了从数据准备到模型部署的AI全流程开发,兼容开发者的使用习惯,支持多种引擎和用户场景,使用自由度较高。针对AI开发的每个环节,Standard功能使用相对自由,您可以根据实际需要选择其中的环节。下文介绍使用ModelArts平台,从准备数据到完成模型开发上线的全流程。 图1 Standard使用流程 表1 使用流程说明 流程 子任务 说明 详细指导 配置权限 配置ModelArts委托授权 ModelArts功能使用还依赖与其他云服务的交互,需要先配置委托授权,允许ModelArts访问相关依赖服务。 快速配置ModelArts委托授权 创建OBS桶(可选) 创建OBS桶用于ModelArts存储数据 由于ModelArts本身没有数据存储的功能,使用Modelarts Standard进行AI开发过程中的输入数据、输出数据、中间缓存数据都可以在OBS桶中进行存储、读取。因此,建议您在使用ModelArts之前先创建一个OBS桶。 创建OBS桶可以提前完成,也可以在后续使用到时再创建。 创建OBS桶用于ModelArts存储数据 准备资源(可选) 创建Standard专属资源池 ModelArts Standard支持公共资源池和专属资源池。 公共资源池:方便快捷,无需创建,创建训练推理任务时直接选择即可。此时,忽略此步骤。 专属资源池:用户独占资源,需要先购买创建。如果使用专属资源池,需要完成此步骤。 创建Standard专属资源池 准备数据(可选) 创建数据集 ModelArts Standard提供了数据管理功能,用户可以在ModelArts Standard中创建数据集,用于管理、预处理、标注数据。 如果用户已经准备了可用于训练的数据,直接上传到OBS即可,无需使用数据管理功能。 创建数据集 标注数据 发布数据集 开发调试 创建Notebook 创建一个Notebook作为开发环境,用于调试训练和推理代码。 建议先在开发环境中调试完成训练代码后再创建生产训练任务。 创建Notebook实例 训练模型 准备算法 创建训练作业前需要先准备算法,可以订阅AI Gallery中的算法,也可以使用用户自己的算法。 准备算法 创建训练作业 创建一个训练作业,选择可用的数据集版本,并使用前面编写完成的训练脚本。训练完成后,将生成模型并存储至OBS中。 创建训练作业 管理模型 编写推理代码和配置文件 针对您生成的模型,建议您按照ModelArts提供的模型包规范,编写推理代码和配置文件,并将推理代码和配置文件存储至训练输出位置。 模型包规范介绍 创建模型 将训练完成的模型导入至ModelArts创建为模型,方便将模型部署上线。 创建模型 部署模型 部署服务 ModelArts支持将模型部署为在线服务、批量服务和边缘服务。 部署为在线服务 部署为批量服务 访问服务 服务部署完成后,针对在线服务和边缘服务,您可以访问并使用服务,针对批量服务,您可以查看其预测结果。 访问在线服务 查看批量服务预测结果
-
常见问题 在ModelArts控制台界面上单击VS Code接入并在新界面单击打开,未弹出VS Code窗口 远程连接出现弹窗报错:Could not establish connection to xxx 在ModelArts控制台界面上单击VS Code接入并在新界面单击打开,VS Code打开后未进行远程连接 报错“ssh: connect to host xxx.pem port xxxxx: Connection refused”如何解决? 报错“no such identity: C:/Users/xx /test.pem: No such file or directory”如何解决? 报错“Bad owner or permissions on C:\Users\Administrator/.ssh/config”或“Connection permission denied (publickey)”如何解决?
-
背景说明 WebSocket是一种网络传输协议,可在单个TCP连接上进行全双工通信,位于OSI模型的应用层。WebSocket协议在2011年由IETF标准化为RFC 6455,后由RFC 7936补充规范。Web IDL中的WebSocket API由W3C标准化。 WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就可以建立持久性的连接,并进行双向数据传输。
-
ModelArts的预置镜像使用场景 ModelArts给用户提供了一组预置镜像,用户可以直接使用预置镜像创建Notebook实例,在实例中进行依赖安装与配置后,保存为自定义镜像,可直接用于ModelArts训练,而不需要做适配。同时也可以使用预置镜像直接提交训练作业、创建模型等。 ModelArts提供的预置镜像版本是依据用户反馈和版本稳定性决定的。当用户的功能开发基于ModelArts提供的版本能够满足的时候,比如用户开发基于MindSpore1.X,建议用户使用预置镜像,这些镜像经过充分的功能验证,并且已经预置了很多常用的安装包,用户无需花费过多的时间来配置环境即可使用。 ModelArts默认提供了一组预置镜像供开发使用,这些镜像有以下特点: 零配置,即开即用,面向特定的场景,将AI开发过程中常用的依赖环境进行固化,提供合适的软件、操作系统、网络等配置策略,通过在硬件上的充分测试,确保其兼容性和性能最合适。 方便自定义,预置镜像已经在SWR仓库中,通过对预置镜像的扩展完成自定义镜像注册。 安全可信,基于安全加固最佳实践,访问策略、用户权限划分、开发软件 漏洞扫描 、操作系统安全加固等方式,确保镜像使用的安全性。
共100000条
- 1
- ...
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- ...
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
- 572
- 573
- 574
- 575
- 576
- 577
- 578
- 579
- 580
- 581
- 582
- 583
- 584
- 585
- 586
- 587
- 588
- 589
- 590
- 591
- 592
- 593
- 594
- 595
- 596
- 597
- 598
- 599
- 600
- 601
- 602
- 603
- 604
- 605
- 606
- 607
- 608
- 609
- 610
- 611
- 612
- 613
- 614
- 615
- 616
- 617
- 618
- 619
- 620
- 621
- 622
- 623
- 624
- 625
- 626
- 627
- 628
- 629
- 630
- 631
- 632
- 633
- 634
- 635
- 636
- 637
- 638
- 639
- 640
- 641
- 642
- 643
- 644
- 645
- 646
- 647
- 648
- 649
- 650
- 651
- 652
- 653
- 654
- 655
- 656
- 657
- 658
- 659
- 660
- 661
- 662
- 663
- 664
- 665
- 666
- 667
- 668
- 669
- 670
- 671
- 672
- 673
- 674
- 675
- 676
- 677
- 678
- 679
- 680
- 681
- 682
- 683
- 684
- 685
- 686
- 687
- 688
- 689
- 690
- 691
- 692
- 693
- 694
- 695
- 696
- 697
- 698
- 699
- 700
- 701
- 702
- 703
- 704
- 705
- 706
- 707
- 708
- 709
- 710
- 711
- 712
- 713
- 714
- 715
- 716
- 717
- 718
- 719
- 720
- 721
- 722
- 723
- 724
- 725
- 726
- 727
- 728
- 729
- 730
- 731
- 732
- 733
- 734
- 735
- 736
- 737
- 738
- 739
- 740
- 741
- 742
- 743
- 744
- 745
- 746
- 747
- 748
- 749
- 750
- 751
- 752
- 753
- 754
- 755
- 756
- 757
- 758
- 759
- 760
- 761
- 762
- 763
- 764
- 765
- 766
- 767
- 768
- 769
- 770
- 771
- 772
- 773
- 774
- 775
- 776
- 777
- 778
- 779
- 780
- 781
- 782
- 783
- 784
- 785
- 786
- 787
- 788
- 789
- 790
- 791
- 792
- 793
- 794
- 795
- 796
- 797
- 798
- 799
- 800
- 801
- 802
- 803
- 804
- 805
- 806
- 807
- 808
- 809
- 810
- 811
- 812
- 813
- 814
- 815
- 816
- 817
- 818
- 819
- 820
- 821
- 822
- 823
- 824
- 825
- 826
- 827
- 828
- 829
- 830
- 831
- 832
- 833
- 834
- 835
- 836
- 837
- 838
- 839
- 840
- 841
- 842
- 843
- 844
- 845
- 846
- 847
- 848
- 849
- 850
- 851
- 852
- 853
- 854
- 855
- 856
- 857
- 858
- 859
- 860
- 861
- 862
- 863
- 864
- 865
- 866
- 867
- 868
- 869
- 870
- 871
- 872
- 873
- 874
- 875
- 876
- 877
- 878
- 879
- 880
- 881
- 882
- 883
- 884
- 885
- 886
- 887
- 888
- 889
- 890
- 891
- 892
- 893
- 894
- 895
- 896
- 897
- 898
- 899
- 900
- 901
- 902
- 903
- 904
- 905
- 906
- 907
- 908
- 909
- 910
- 911
- 912
- 913
- 914
- 915
- 916
- 917
- 918
- 919
- 920
- 921
- 922
- 923
- 924
- 925
- 926
- 927
- 928
- 929
- 930
- 931
- 932
- 933
- 934
- 935
- 936
- 937
- 938
- 939
- 940
- 941
- 942
- 943
- 944
- 945
- 946
- 947
- 948
- 949
- 950
- 951
- 952
- 953
- 954
- 955
- 956
- 957
- 958
- 959
- 960
- 961
- 962
- 963
- 964
- 965
- 966
- 967
- 968
- 969
- 970
- 971
- 972
- 973
- 974
- 975
- 976
- 977
- 978
- 979
- 980
- 981
- 982
- 983
- 984
- 985
- 986
- 987
- 988
- 989
- 990
- 991
- 992
- 993
- 994
- 995
- 996
- 997
- 998
- 999
- 1000
- 1001
- 1002
- 1003
- 1004
- 1005
- 1006
- 1007
- 1008
- 1009
- 1010
- 1011
- 1012
- 1013
- 1014
- 1015
- 1016
- 1017
- 1018
- 1019
- 1020
- 1021
- 1022
- 1023
- 1024
- 1025
- 1026
- 1027
- 1028
- 1029
- 1030
- 1031
- 1032
- 1033
- 1034
- 1035
- 1036
- 1037
- 1038
- 1039
- 1040
- 1041
- 1042
- 1043
- 1044
- 1045
- 1046
- 1047
- 1048
- 1049
- 1050
- 1051
- 1052
- 1053
- 1054
- 1055
- 1056
- 1057
- 1058
- 1059
- 1060
- 1061
- 1062
- 1063
- 1064
- 1065
- 1066
- 1067
- 1068
- 1069
- 1070
- 1071
- 1072
- 1073
- 1074
- 1075
- 1076
- 1077
- 1078
- 1079
- 1080
- 1081
- 1082
- 1083
- 1084
- 1085
- 1086
- 1087
- 1088
- 1089
- 1090
- 1091
- 1092
- 1093
- 1094
- 1095
- 1096
- 1097
- 1098
- 1099
- 1100
- 1101
- 1102
- 1103
- 1104
- 1105
- 1106
- 1107
- 1108
- 1109
- 1110
- 1111
- 1112
- 1113
- 1114
- 1115
- 1116
- 1117
- 1118
- 1119
- 1120
- 1121
- 1122
- 1123
- 1124
- 1125
- 1126
- 1127
- 1128
- 1129
- 1130
- 1131
- 1132
- 1133
- 1134
- 1135
- 1136
- 1137
- 1138
- 1139
- 1140
- 1141
- 1142
- 1143
- 1144
- 1145
- 1146
- 1147
- 1148
- 1149
- 1150
- 1151
- 1152
- 1153
- 1154
- 1155
- 1156
- 1157
- 1158
- 1159
- 1160
- 1161
- 1162
- 1163
- 1164
- 1165
- 1166
- 1167
- 1168
- 1169
- 1170
- 1171
- 1172
- 1173
- 1174
- 1175
- 1176
- 1177
- 1178
- 1179
- 1180
- 1181
- 1182
- 1183
- 1184
- 1185
- 1186
- 1187
- 1188
- 1189
- 1190
- 1191
- 1192
- 1193
- 1194
- 1195
- 1196
- 1197
- 1198
- 1199
- 1200
- 1201
- 1202
- 1203
- 1204
- 1205
- 1206
- 1207
- 1208
- 1209
- 1210
- 1211
- 1212
- 1213
- 1214
- 1215
- 1216
- 1217
- 1218
- 1219
- 1220
- 1221
- 1222
- 1223
- 1224
- 1225
- 1226
- 1227
- 1228
- 1229
- 1230
- 1231
- 1232
- 1233
- 1234
- 1235
- 1236
- 1237
- 1238
- 1239
- 1240
- 1241
- 1242
- 1243
- 1244
- 1245
- 1246
- 1247
- 1248
- 1249
- 1250
- 1251
- 1252
- 1253
- 1254
- 1255
- 1256
- 1257
- 1258
- 1259
- 1260
- 1261
- 1262
- 1263
- 1264
- 1265
- 1266
- 1267
- 1268
- 1269
- 1270
- 1271
- 1272
- 1273
- 1274
- 1275
- 1276
- 1277
- 1278
- 1279
- 1280
- 1281
- 1282
- 1283
- 1284
- 1285
- 1286
- 1287
- 1288
- 1289
- 1290
- 1291
- 1292
- 1293
- 1294
- 1295
- 1296
- 1297
- 1298
- 1299
- 1300
- 1301
- 1302
- 1303
- 1304
- 1305
- 1306
- 1307
- 1308
- 1309
- 1310
- 1311
- 1312
- 1313
- 1314
- 1315
- 1316
- 1317
- 1318
- 1319
- 1320
- 1321
- 1322
- 1323
- 1324
- 1325
- 1326
- 1327
- 1328
- 1329
- 1330
- 1331
- 1332
- 1333
- 1334
- 1335
- 1336
- 1337
- 1338
- 1339
- 1340
- 1341
- 1342
- 1343
- 1344
- 1345
- 1346
- 1347
- 1348
- 1349
- 1350
- 1351
- 1352
- 1353
- 1354
- 1355
- 1356
- 1357
- 1358
- 1359
- 1360
- 1361
- 1362
- 1363
- 1364
- 1365
- 1366
- 1367
- 1368
- 1369
- 1370
- 1371
- 1372
- 1373
- 1374
- 1375
- 1376
- 1377
- 1378
- 1379
- 1380
- 1381
- 1382
- 1383
- 1384
- 1385
- 1386
- 1387
- 1388
- 1389
- 1390
- 1391
- 1392
- 1393
- 1394
- 1395
- 1396
- 1397
- 1398
- 1399
- 1400
- 1401
- 1402
- 1403
- 1404
- 1405
- 1406
- 1407
- 1408
- 1409
- 1410
- 1411
- 1412
- 1413
- 1414
- 1415
- 1416
- 1417
- 1418
- 1419
- 1420
- 1421
- 1422
- 1423
- 1424
- 1425
- 1426
- 1427
- 1428
- 1429
- 1430
- 1431
- 1432
- 1433
- 1434
- 1435
- 1436
- 1437
- 1438
- 1439
- 1440
- 1441
- 1442
- 1443
- 1444
- 1445
- 1446
- 1447
- 1448
- 1449
- 1450
- 1451
- 1452
- 1453
- 1454
- 1455
- 1456
- 1457
- 1458
- 1459
- 1460
- 1461
- 1462
- 1463
- 1464
- 1465
- 1466
- 1467
- 1468
- 1469
- 1470
- 1471
- 1472
- 1473
- 1474
- 1475
- 1476
- 1477
- 1478
- 1479
- 1480
- 1481
- 1482
- 1483
- 1484
- 1485
- 1486
- 1487
- 1488
- 1489
- 1490
- 1491
- 1492
- 1493
- 1494
- 1495
- 1496
- 1497
- 1498
- 1499
- 1500
- 1501
- 1502
- 1503
- 1504
- 1505
- 1506
- 1507
- 1508
- 1509
- 1510
- 1511
- 1512
- 1513
- 1514
- 1515
- 1516
- 1517
- 1518
- 1519
- 1520
- 1521
- 1522
- 1523
- 1524
- 1525
- 1526
- 1527
- 1528
- 1529
- 1530
- 1531
- 1532
- 1533
- 1534
- 1535
- 1536
- 1537
- 1538
- 1539
- 1540
- 1541
- 1542
- 1543
- 1544
- 1545
- 1546
- 1547
- 1548
- 1549
- 1550
- 1551
- 1552
- 1553
- 1554
- 1555
- 1556
- 1557
- 1558
- 1559
- 1560
- 1561
- 1562
- 1563
- 1564
- 1565
- 1566
- 1567
- 1568
- 1569
- 1570
- 1571
- 1572
- 1573
- 1574
- 1575
- 1576
- 1577
- 1578
- 1579
- 1580
- 1581
- 1582
- 1583
- 1584
- 1585
- 1586
- 1587
- 1588
- 1589
- 1590
- 1591
- 1592
- 1593
- 1594
- 1595
- 1596
- 1597
- 1598
- 1599
- 1600
- 1601
- 1602
- 1603
- 1604
- 1605
- 1606
- 1607
- 1608
- 1609
- 1610
- 1611
- 1612
- 1613
- 1614
- 1615
- 1616
- 1617
- 1618
- 1619
- 1620
- 1621
- 1622
- 1623
- 1624
- 1625
- 1626
- 1627
- 1628
- 1629
- 1630
- 1631
- 1632
- 1633
- 1634
- 1635
- 1636
- 1637
- 1638
- 1639
- 1640
- 1641
- 1642
- 1643
- 1644
- 1645
- 1646
- 1647
- 1648
- 1649
- 1650
- 1651
- 1652
- 1653
- 1654
- 1655
- 1656
- 1657
- 1658
- 1659
- 1660
- 1661
- 1662
- 1663
- 1664
- 1665
- 1666
- 1667
- 1668
- 1669
- 1670
- 1671
- 1672
- 1673
- 1674
- 1675
- 1676
- 1677
- 1678
- 1679
- 1680
- 1681
- 1682
- 1683
- 1684
- 1685
- 1686
- 1687
- 1688
- 1689
- 1690
- 1691
- 1692
- 1693
- 1694
- 1695
- 1696
- 1697
- 1698
- 1699
- 1700
- 1701
- 1702
- 1703
- 1704
- 1705
- 1706
- 1707
- 1708
- 1709
- 1710
- 1711
- 1712
- 1713
- 1714
- 1715
- 1716
- 1717
- 1718
- 1719
- 1720
- 1721
- 1722
- 1723
- 1724
- 1725
- 1726
- 1727
- 1728
- 1729
- 1730
- 1731
- 1732
- 1733
- 1734
- 1735
- 1736
- 1737
- 1738
- 1739
- 1740
- 1741
- 1742
- 1743
- 1744
- 1745
- 1746
- 1747
- 1748
- 1749
- 1750
- 1751
- 1752
- 1753
- 1754
- 1755
- 1756
- 1757
- 1758
- 1759
- 1760
- 1761
- 1762
- 1763
- 1764
- 1765
- 1766
- 1767
- 1768
- 1769
- 1770
- 1771
- 1772
- 1773
- 1774
- 1775
- 1776
- 1777
- 1778
- 1779
- 1780
- 1781
- 1782
- 1783
- 1784
- 1785
- 1786
- 1787
- 1788
- 1789
- 1790
- 1791
- 1792
- 1793
- 1794
- 1795
- 1796
- 1797
- 1798
- 1799
- 1800
- 1801
- 1802
- 1803
- 1804
- 1805
- 1806
- 1807
- 1808
- 1809
- 1810
- 1811
- 1812
- 1813
- 1814
- 1815
- 1816
- 1817
- 1818
- 1819
- 1820
- 1821
- 1822
- 1823
- 1824
- 1825
- 1826
- 1827
- 1828
- 1829
- 1830
- 1831
- 1832
- 1833
- 1834
- 1835
- 1836
- 1837
- 1838
- 1839
- 1840
- 1841
- 1842
- 1843
- 1844
- 1845
- 1846
- 1847
- 1848
- 1849
- 1850
- 1851
- 1852
- 1853
- 1854
- 1855
- 1856
- 1857
- 1858
- 1859
- 1860
- 1861
- 1862
- 1863
- 1864
- 1865
- 1866
- 1867
- 1868
- 1869
- 1870
- 1871
- 1872
- 1873
- 1874
- 1875
- 1876
- 1877
- 1878
- 1879
- 1880
- 1881
- 1882
- 1883
- 1884
- 1885
- 1886
- 1887
- 1888
- 1889
- 1890
- 1891
- 1892
- 1893
- 1894
- 1895
- 1896
- 1897
- 1898
- 1899
- 1900
- 1901
- 1902
- 1903
- 1904
- 1905
- 1906
- 1907
- 1908
- 1909
- 1910
- 1911
- 1912
- 1913
- 1914
- 1915
- 1916
- 1917
- 1918
- 1919
- 1920
- 1921
- 1922
- 1923
- 1924
- 1925
- 1926
- 1927
- 1928
- 1929
- 1930
- 1931
- 1932
- 1933
- 1934
- 1935
- 1936
- 1937
- 1938
- 1939
- 1940
- 1941
- 1942
- 1943
- 1944
- 1945
- 1946
- 1947
- 1948
- 1949
- 1950
- 1951
- 1952
- 1953
- 1954
- 1955
- 1956
- 1957
- 1958
- 1959
- 1960
- 1961
- 1962
- 1963
- 1964
- 1965
- 1966
- 1967
- 1968
- 1969
- 1970
- 1971
- 1972
- 1973
- 1974
- 1975
- 1976
- 1977
- 1978
- 1979
- 1980
- 1981
- 1982
- 1983
- 1984
- 1985
- 1986
- 1987
- 1988
- 1989
- 1990
- 1991
- 1992
- 1993
- 1994
- 1995
- 1996
- 1997
- 1998
- 1999
- 2000
- 2001
- 2002
- 2003
- 2004
- 2005
- 2006
- 2007
- 2008
- 2009
- 2010
- 2011
- 2012
- 2013
- 2014
- 2015
- 2016
- 2017
- 2018
- 2019
- 2020
- 2021
- 2022
- 2023
- 2024
- 2025
- 2026
- 2027
- 2028
- 2029
- 2030
- 2031
- 2032
- 2033
- 2034
- 2035
- 2036
- 2037
- 2038
- 2039
- 2040
- 2041
- 2042
- 2043
- 2044
- 2045
- 2046
- 2047
- 2048
- 2049
- 2050
- 2051
- 2052
- 2053
- 2054
- 2055
- 2056
- 2057
- 2058
- 2059
- 2060
- 2061
- 2062
- 2063
- 2064
- 2065
- 2066
- 2067
- 2068
- 2069
- 2070
- 2071
- 2072
- 2073
- 2074
- 2075
- 2076
- 2077
- 2078
- 2079
- 2080
- 2081
- 2082
- 2083
- 2084
- 2085
- 2086
- 2087
- 2088
- 2089
- 2090
- 2091
- 2092
- 2093
- 2094
- 2095
- 2096
- 2097
- 2098
- 2099
- 2100
- 2101
- 2102
- 2103
- 2104
- 2105
- 2106
- 2107
- 2108
- 2109
- 2110
- 2111
- 2112
- 2113
- 2114
- 2115
- 2116
- 2117
- 2118
- 2119
- 2120
- 2121
- 2122
- 2123
- 2124
- 2125
- 2126
- 2127
- 2128
- 2129
- 2130
- 2131
- 2132
- 2133
- 2134
- 2135
- 2136
- 2137
- 2138
- 2139
- 2140
- 2141
- 2142
- 2143
- 2144
- 2145
- 2146
- 2147
- 2148
- 2149
- 2150
- 2151
- 2152
- 2153
- 2154
- 2155
- 2156
- 2157
- 2158
- 2159
- 2160
- 2161
- 2162
- 2163
- 2164
- 2165
- 2166
- 2167
- 2168
- 2169
- 2170
- 2171
- 2172
- 2173
- 2174
- 2175
- 2176
- 2177
- 2178
- 2179
- 2180
- 2181
- 2182
- 2183
- 2184
- 2185
- 2186
- 2187
- 2188
- 2189
- 2190
- 2191
- 2192
- 2193
- 2194
- 2195
- 2196
- 2197
- 2198
- 2199
- 2200
- 2201
- 2202
- 2203
- 2204
- 2205
- 2206
- 2207
- 2208
- 2209
- 2210
- 2211
- 2212
- 2213
- 2214
- 2215
- 2216
- 2217
- 2218
- 2219
- 2220
- 2221
- 2222
- 2223
- 2224
- 2225
- 2226
- 2227
- 2228
- 2229
- 2230
- 2231
- 2232
- 2233
- 2234
- 2235
- 2236
- 2237
- 2238
- 2239
- 2240
- 2241
- 2242
- 2243
- 2244
- 2245
- 2246
- 2247
- 2248
- 2249
- 2250
- 2251
- 2252
- 2253
- 2254
- 2255
- 2256
- 2257
- 2258
- 2259
- 2260
- 2261
- 2262
- 2263
- 2264
- 2265
- 2266
- 2267
- 2268
- 2269
- 2270
- 2271
- 2272
- 2273
- 2274
- 2275
- 2276
- 2277
- 2278
- 2279
- 2280
- 2281
- 2282
- 2283
- 2284
- 2285
- 2286
- 2287
- 2288
- 2289
- 2290
- 2291
- 2292
- 2293
- 2294
- 2295
- 2296
- 2297
- 2298
- 2299
- 2300
- 2301
- 2302
- 2303
- 2304
- 2305
- 2306
- 2307
- 2308
- 2309
- 2310
- 2311
- 2312
- 2313
- 2314
- 2315
- 2316
- 2317
- 2318
- 2319
- 2320
- 2321
- 2322
- 2323
- 2324
- 2325
- 2326
- 2327
- 2328
- 2329
- 2330
- 2331
- 2332
- 2333
- 2334
- 2335
- 2336
- 2337
- 2338
- 2339
- 2340
- 2341
- 2342
- 2343
- 2344
- 2345
- 2346
- 2347
- 2348
- 2349
- 2350
- 2351
- 2352
- 2353
- 2354
- 2355
- 2356
- 2357
- 2358
- 2359
- 2360
- 2361
- 2362
- 2363
- 2364
- 2365
- 2366
- 2367
- 2368
- 2369
- 2370
- 2371
- 2372
- 2373
- 2374
- 2375
- 2376
- 2377
- 2378
- 2379
- 2380
- 2381
- 2382
- 2383
- 2384
- 2385
- 2386
- 2387
- 2388
- 2389
- 2390
- 2391
- 2392
- 2393
- 2394
- 2395
- 2396
- 2397
- 2398
- 2399
- 2400
- 2401
- 2402
- 2403
- 2404
- 2405
- 2406
- 2407
- 2408
- 2409
- 2410
- 2411
- 2412
- 2413
- 2414
- 2415
- 2416
- 2417
- 2418
- 2419
- 2420
- 2421
- 2422
- 2423
- 2424
- 2425
- 2426
- 2427
- 2428
- 2429
- 2430
- 2431
- 2432
- 2433
- 2434
- 2435
- 2436
- 2437
- 2438
- 2439
- 2440
- 2441
- 2442
- 2443
- 2444
- 2445
- 2446
- 2447
- 2448
- 2449
- 2450
- 2451
- 2452
- 2453
- 2454
- 2455
- 2456
- 2457
- 2458
- 2459
- 2460
- 2461
- 2462
- 2463
- 2464
- 2465
- 2466
- 2467
- 2468
- 2469
- 2470
- 2471
- 2472
- 2473
- 2474
- 2475
- 2476
- 2477
- 2478
- 2479
- 2480
- 2481
- 2482
- 2483
- 2484
- 2485
- 2486
- 2487
- 2488
- 2489
- 2490
- 2491
- 2492
- 2493
- 2494
- 2495
- 2496
- 2497
- 2498
- 2499
- 2500
- 2501
- 2502
- 2503
- 2504
- 2505
- 2506
- 2507
- 2508
- 2509
- 2510
- 2511
- 2512
- 2513
- 2514
- 2515
- 2516
- 2517
- 2518
- 2519
- 2520
- 2521
- 2522
- 2523
- 2524
- 2525
- 2526
- 2527
- 2528
- 2529
- 2530
- 2531
- 2532
- 2533
- 2534
- 2535
- 2536
- 2537
- 2538
- 2539
- 2540
- 2541
- 2542
- 2543
- 2544
- 2545
- 2546
- 2547
- 2548
- 2549
- 2550
- 2551
- 2552
- 2553
- 2554
- 2555
- 2556
- 2557
- 2558
- 2559
- 2560
- 2561
- 2562
- 2563
- 2564
- 2565
- 2566
- 2567
- 2568
- 2569
- 2570
- 2571
- 2572
- 2573
- 2574
- 2575
- 2576
- 2577
- 2578
- 2579
- 2580
- 2581
- 2582
- 2583
- 2584
- 2585
- 2586
- 2587
- 2588
- 2589
- 2590
- 2591
- 2592
- 2593
- 2594
- 2595
- 2596
- 2597
- 2598
- 2599
- 2600
- 2601
- 2602
- 2603
- 2604
- 2605
- 2606
- 2607
- 2608
- 2609
- 2610
- 2611
- 2612
- 2613
- 2614
- 2615
- 2616
- 2617
- 2618
- 2619
- 2620
- 2621
- 2622
- 2623
- 2624
- 2625
- 2626
- 2627
- 2628
- 2629
- 2630
- 2631
- 2632
- 2633
- 2634
- 2635
- 2636
- 2637
- 2638
- 2639
- 2640
- 2641
- 2642
- 2643
- 2644
- 2645
- 2646
- 2647
- 2648
- 2649
- 2650
- 2651
- 2652
- 2653
- 2654
- 2655
- 2656
- 2657
- 2658
- 2659
- 2660
- 2661
- 2662
- 2663
- 2664
- 2665
- 2666
- 2667
- 2668
- 2669
- 2670
- 2671
- 2672
- 2673
- 2674
- 2675
- 2676
- 2677
- 2678
- 2679
- 2680
- 2681
- 2682
- 2683
- 2684
- 2685
- 2686
- 2687
- 2688
- 2689
- 2690
- 2691
- 2692
- 2693
- 2694
- 2695
- 2696
- 2697
- 2698
- 2699
- 2700
- 2701
- 2702
- 2703
- 2704
- 2705
- 2706
- 2707
- 2708
- 2709
- 2710
- 2711
- 2712
- 2713
- 2714
- 2715
- 2716
- 2717
- 2718
- 2719
- 2720
- 2721
- 2722
- 2723
- 2724
- 2725
- 2726
- 2727
- 2728
- 2729
- 2730
- 2731
- 2732
- 2733
- 2734
- 2735
- 2736
- 2737
- 2738
- 2739
- 2740
- 2741
- 2742
- 2743
- 2744
- 2745
- 2746
- 2747
- 2748
- 2749
- 2750
- 2751
- 2752
- 2753
- 2754
- 2755
- 2756
- 2757
- 2758
- 2759
- 2760
- 2761
- 2762
- 2763
- 2764
- 2765
- 2766
- 2767
- 2768
- 2769
- 2770
- 2771
- 2772
- 2773
- 2774
- 2775
- 2776
- 2777
- 2778
- 2779
- 2780
- 2781
- 2782
- 2783
- 2784
- 2785
- 2786
- 2787
- 2788
- 2789
- 2790
- 2791
- 2792
- 2793
- 2794
- 2795
- 2796
- 2797
- 2798
- 2799
- 2800
- 2801
- 2802
- 2803
- 2804
- 2805
- 2806
- 2807
- 2808
- 2809
- 2810
- 2811
- 2812
- 2813
- 2814
- 2815
- 2816
- 2817
- 2818
- 2819
- 2820
- 2821
- 2822
- 2823
- 2824
- 2825
- 2826
- 2827
- 2828
- 2829
- 2830
- 2831
- 2832
- 2833
- 2834
- 2835
- 2836
- 2837
- 2838
- 2839
- 2840
- 2841
- 2842
- 2843
- 2844
- 2845
- 2846
- 2847
- 2848
- 2849
- 2850
- 2851
- 2852
- 2853
- 2854
- 2855
- 2856
- 2857
- 2858
- 2859
- 2860
- 2861
- 2862
- 2863
- 2864
- 2865
- 2866
- 2867
- 2868
- 2869
- 2870
- 2871
- 2872
- 2873
- 2874
- 2875
- 2876
- 2877
- 2878
- 2879
- 2880
- 2881
- 2882
- 2883
- 2884
- 2885
- 2886
- 2887
- 2888
- 2889
- 2890
- 2891
- 2892
- 2893
- 2894
- 2895
- 2896
- 2897
- 2898
- 2899
- 2900
- 2901
- 2902
- 2903
- 2904
- 2905
- 2906
- 2907
- 2908
- 2909
- 2910
- 2911
- 2912
- 2913
- 2914
- 2915
- 2916
- 2917
- 2918
- 2919
- 2920
- 2921
- 2922
- 2923
- 2924
- 2925
- 2926
- 2927
- 2928
- 2929
- 2930
- 2931
- 2932
- 2933
- 2934
- 2935
- 2936
- 2937
- 2938
- 2939
- 2940
- 2941
- 2942
- 2943
- 2944
- 2945
- 2946
- 2947
- 2948
- 2949
- 2950
- 2951
- 2952
- 2953
- 2954
- 2955
- 2956
- 2957
- 2958
- 2959
- 2960
- 2961
- 2962
- 2963
- 2964
- 2965
- 2966
- 2967
- 2968
- 2969
- 2970
- 2971
- 2972
- 2973
- 2974
- 2975
- 2976
- 2977
- 2978
- 2979
- 2980
- 2981
- 2982
- 2983
- 2984
- 2985
- 2986
- 2987
- 2988
- 2989
- 2990
- 2991
- 2992
- 2993
- 2994
- 2995
- 2996
- 2997
- 2998
- 2999
- 3000
- 3001
- 3002
- 3003
- 3004
- 3005
- 3006
- 3007
- 3008
- 3009
- 3010
- 3011
- 3012
- 3013
- 3014
- 3015
- 3016
- 3017
- 3018
- 3019
- 3020
- 3021
- 3022
- 3023
- 3024
- 3025
- 3026
- 3027
- 3028
- 3029
- 3030
- 3031
- 3032
- 3033
- 3034
- 3035
- 3036
- 3037
- 3038
- 3039
- 3040
- 3041
- 3042
- 3043
- 3044
- 3045
- 3046
- 3047
- 3048
- 3049
- 3050
- 3051
- 3052
- 3053
- 3054
- 3055
- 3056
- 3057
- 3058
- 3059
- 3060
- 3061
- 3062
- 3063
- 3064
- 3065
- 3066
- 3067
- 3068
- 3069
- 3070
- 3071
- 3072
- 3073
- 3074
- 3075
- 3076
- 3077
- 3078
- 3079
- 3080
- 3081
- 3082
- 3083
- 3084
- 3085
- 3086
- 3087
- 3088
- 3089
- 3090
- 3091
- 3092
- 3093
- 3094
- 3095
- 3096
- 3097
- 3098
- 3099
- 3100
- 3101
- 3102
- 3103
- 3104
- 3105
- 3106
- 3107
- 3108
- 3109
- 3110
- 3111
- 3112
- 3113
- 3114
- 3115
- 3116
- 3117
- 3118
- 3119
- 3120
- 3121
- 3122
- 3123
- 3124
- 3125
- 3126
- 3127
- 3128
- 3129
- 3130
- 3131
- 3132
- 3133
- 3134
- 3135
- 3136
- 3137
- 3138
- 3139
- 3140
- 3141
- 3142
- 3143
- 3144
- 3145
- 3146
- 3147
- 3148
- 3149
- 3150
- 3151
- 3152
- 3153
- 3154
- 3155
- 3156
- 3157
- 3158
- 3159
- 3160
- 3161
- 3162
- 3163
- 3164
- 3165
- 3166
- 3167
- 3168
- 3169
- 3170
- 3171
- 3172
- 3173
- 3174
- 3175
- 3176
- 3177
- 3178
- 3179
- 3180
- 3181
- 3182
- 3183
- 3184
- 3185
- 3186
- 3187
- 3188
- 3189
- 3190
- 3191
- 3192
- 3193
- 3194
- 3195
- 3196
- 3197
- 3198
- 3199
- 3200
- 3201
- 3202
- 3203
- 3204
- 3205
- 3206
- 3207
- 3208
- 3209
- 3210
- 3211
- 3212
- 3213
- 3214
- 3215
- 3216
- 3217
- 3218
- 3219
- 3220
- 3221
- 3222
- 3223
- 3224
- 3225
- 3226
- 3227
- 3228
- 3229
- 3230
- 3231
- 3232
- 3233
- 3234
- 3235
- 3236
- 3237
- 3238
- 3239
- 3240
- 3241
- 3242
- 3243
- 3244
- 3245
- 3246
- 3247
- 3248
- 3249
- 3250
- 3251
- 3252
- 3253
- 3254
- 3255
- 3256
- 3257
- 3258
- 3259
- 3260
- 3261
- 3262
- 3263
- 3264
- 3265
- 3266
- 3267
- 3268
- 3269
- 3270
- 3271
- 3272
- 3273
- 3274
- 3275
- 3276
- 3277
- 3278
- 3279
- 3280
- 3281
- 3282
- 3283
- 3284
- 3285
- 3286
- 3287
- 3288
- 3289
- 3290
- 3291
- 3292
- 3293
- 3294
- 3295
- 3296
- 3297
- 3298
- 3299
- 3300
- 3301
- 3302
- 3303
- 3304
- 3305
- 3306
- 3307
- 3308
- 3309
- 3310
- 3311
- 3312
- 3313
- 3314
- 3315
- 3316
- 3317
- 3318
- 3319
- 3320
- 3321
- 3322
- 3323
- 3324
- 3325
- 3326
- 3327
- 3328
- 3329
- 3330
- 3331
- 3332
- 3333
- 3333
推荐文章