# 目录 - [目录](#目录) - [Wide&Deep概述](#Wide&Deep概述) - [模型架构](#模型架构) - [数据集](#数据集) - [环境要求](#环境要求) - [快速入门](#快速入门) - [脚本说明](#脚本说明) - [脚本和样例代码](#脚本和样例代码) - [脚本参数](#脚本参数) - [训练脚本参数](#训练脚本参数) - [预处理脚本参数](#预处理脚本参数) - [准备数据集](#准备数据集) - [处理真实世界数据](#处理真实世界数据) - [生成和处理合成数据](#生成和处理合成数据) - [训练过程](#训练过程) - [单机训练](#单机训练) - [单机训练缓存模式](#单机训练缓存模式) - [分布式训练](#分布式训练) - [参数服务器](#参数服务器) - [评估过程](#评估过程) - [Evaluation Process](#evaluation-process) - [推理过程](#推理过程) - [导出MindIR](#导出mindir) - [在Ascend310执行推理](#在ascend310执行推理) - [result](#result) - [模型描述](#模型描述) - [性能](#性能) - [训练性能](#训练性能) - [评估性能](#评估性能) - [极致性能体验](#极致性能体验) - [随机情况说明](#随机情况说明) - [ModelZoo主页](#modelzoo主页) <!-- /TOC --> # Wide&Deep概述 Wide&Deep模型是推荐和点击预测领域的经典模型。 [Wide&Deep推荐系统学习](https://arxiv.org/pdf/1606.07792.pdf)论文中描述了如何实现Wide&Deep。 # 模型架构 Wide&Deep模型训练了宽线性模型和深度学习神经网络,结合了推荐系统的记忆和泛化的优点。 目前我们支持embedding多维度切分并行的主机设备模式和参数服务器模式,且已和诺亚实验室合作实现了超大规模推荐网络的缓存方案([ScaleFreeCTR](https://arxiv.org/abs/2104.08542))。 # 数据集 - [Criteo Kaggle Display Advertising Challenge Dataset](http://go.criteo.net/criteo-research-kaggle-display-advertising-challenge-dataset.tar.gz) # 环境要求 - 硬件(Ascend或GPU) - 准备Ascend或GPU处理器搭建硬件环境。 - 框架 - [MindSpore](https://gitee.com/mindspore/mindspore) - 如需查看详情,请参见如下资源: - [MindSpore教程](https://www.mindspore.cn/tutorials/zh-CN/master/index.html) - [MindSpore Python API](https://www.mindspore.cn/docs/zh-CN/master/index.html) # 快速入门 1. 克隆代码。 ```bash git clone https://gitee.com/mindspore/models.git cd models/official/recommend/wide_and_deep ``` 2. 下载数据集。 > 请参考[1](#数据集)获得下载链接。 ```bash mkdir -p data/origin_data && cd data/origin_data wget DATA_LINK tar -zxvf dac.tar.gz ``` 3. 使用此脚本预处理数据。处理过程可能需要一小时,生成的MindRecord数据存放在data/mindrecord路径下。 ```bash python src/preprocess_data.py --data_path=./data/ --dense_dim=13 --slot_dim=26 --threshold=100 --train_line_count=45840617 --skip_id_convert=0 ``` 4. 开始训练。 数据集准备就绪后,即可在Ascend上单机训练和评估模型。 ```bash python train_and_eval.py --data_path=./data/mindrecord --dataset_type=mindrecord --device_target=Ascend ``` 按如下操作评估模型: ```bash python eval.py --data_path=./data/mindrecord --dataset_type=mindrecord --device_target=Ascend --ckpt_path=./ckpt/widedeep_train-15_2582.ckpt ``` - 在ModelArts上运行(如果想在modelarts中运行,请查看【modelarts】官方文档(https://support.huaweicloud.com/modelarts/),如下开始训练即可) ```python # 在 ModelArts 上训练 8p # (1) 执行 a 或 b。 # a. 在 default_config.yaml 文件上设置“enable_modelarts=True”。 # 在 default_config.yaml 文件上设置“run_distribute=True”。 # 在 default_config.yaml 文件上设置“data_path=/cache/data/criteo_mindrecord/”。 # 在 default_config.yaml 文件上设置您需要的其他参数。 # b. 在网站UI界面添加“enable_modelarts=True”。 # 在网站UI界面添加“run_distribute=True”。 # 在网站UI界面添加“dataset_path=/cache/data/criteo_mindrecord/”。 # 在网站UI界面添加其他参数。 # (2) 将 zip 数据集上传到 S3 存储桶。 (您也可以上传原始数据集,但速度可能很慢。) # (3) 在网站UI界面设置代码目录为“/path/wide_and_deep”。 # (4) 在网站UI界面设置启动文件为“train.py”。 # (5) 将“数据集路径”和“输出文件路径”和“作业日志路径”设置为您在网站UI界面上的路径。 # (6) 创建你的工作。 # # 在 ModelArts 上训练 1p # (1) 执行 a 或 b。 # a. 在 default_config.yaml 文件上设置“enable_modelarts=True”。 # 在 default_config.yaml 文件中设置“dataset_path='/cache/data/criteo_mindrecord/'”。 # 在 default_config.yaml 文件上设置您需要的其他参数。 # b. 在网站UI界面添加“enable_modelarts=True”。 # 在网站UI界面添加“dataset_path=/cache/data/criteo_mindrecord/”。 # 在网站UI界面添加其他参数。 # (2) 将 zip 数据集上传到 S3 存储桶。 (您也可以上传原始数据集,但速度可能很慢。) # (3) 在网站UI界面设置代码目录为“/path/wide_and_deep”。 # (4) 在网站UI界面设置启动文件为“train.py”。 # (5) 将“数据集路径”和“输出文件路径”和“作业日志路径”设置为您在网站UI界面上的路径。 # (6) 创建你的工作。 # # ModelArts 上的 Eval 1p # (1) 执行 a 或 b。 # a. 在 default_config.yaml 文件上设置“enable_modelarts=True”。 # 在 default_config.yaml 文件上设置“ckpt_file='/cache/checkpoint_path/model.ckpt'”。 # 在 default_config.yaml 文件中设置“checkpoint_url='s3://dir_to_trained_ckpt/'”。 # 在 default_config.yaml 文件中设置“dataset_path='/cache/data/criteo_mindrecord/'”。 # 在 default_config.yaml 文件上设置您需要的其他参数。 # b. 在网站UI界面添加“enable_modelarts=True”。 # 在网站UI界面添加“ckpt_file=/cache/checkpoint_path/model.ckpt”。 # 在网站UI界面添加“checkpoint_url=s3://dir_to_trained_ckpt/”。 # 在网站UI界面添加“dataset_path=/cache/data/criteo_mindrecord/”。 # 在网站UI界面添加其他参数。 # (2) 将 zip 数据集上传到 S3 存储桶。 (您也可以上传原始数据集,但速度可能很慢。) # (3) 在网站UI界面设置代码目录为“/path/wide_and_deep”。 # (4) 在网站UI界面设置启动文件为“eval.py”。 # (5) 将“数据集路径”和“输出文件路径”和“作业日志路径”设置为您在网站UI界面上的路径。 # (6) 创建你的工作。 ``` - 在 ModelArts 进行导出 (如果你想在modelarts上运行,可以参考以下文档 [modelarts](https://support.huaweicloud.com/modelarts/)) 1. 使用voc val数据集评估多尺度和翻转s8。评估步骤如下: ```python # (1) 执行 a 或者 b. # a. 在 base_config.yaml 文件中设置 "enable_modelarts=True" # 在 base_config.yaml 文件中设置 "file_name='wide_and_deep'" # 在 base_config.yaml 文件中设置 "file_format='MINDIR'" # 在 base_config.yaml 文件中设置 "checkpoint_url='/The path of checkpoint in S3/'" # 在 base_config.yaml 文件中设置 "ckpt_file='/cache/checkpoint_path/model.ckpt'" # 在 base_config.yaml 文件中设置 其他参数 # b. 在网页上设置 "enable_modelarts=True" # 在网页上设置 "file_name='wide_and_deep'" # 在网页上设置 "file_format='MINDIR'" # 在网页上设置 "checkpoint_url='/The path of checkpoint in S3/'" # 在网页上设置 "ckpt_file='/cache/checkpoint_path/model.ckpt'" # 在网页上设置 其他参数 # (2) 上传你的预训练模型到 S3 桶上 # (3) 在网页上设置你的代码路径为 "/path/wide_and_deep" # (4) 在网页上设置启动文件为 "export.py" # (5) 在网页上设置"训练数据集"、"训练输出文件路径"、"作业日志路径"等 # (6) 创建训练作业 ``` ## 脚本说明 ## 脚本和样例代码 ```bash └── wide_and_deep ├── eval.py ├── README.md ├── script │ ├── cluster_32p.json │ ├── common.sh │ ├── deploy_cluster.sh │ ├── run_auto_parallel_train_cluster.sh │ ├── run_auto_parallel_train.sh │ ├── run_multigpu_train.sh │ ├── run_multinpu_train.sh │ ├── run_parameter_server_train_cluster.sh │ ├── run_parameter_server_train.sh │ ├── run_standalone_train_for_gpu.sh │ └── start_cluster.sh ├──src │ ├── callbacks.py │ ├── config.py │ ├── datasets.py │ ├── generate_synthetic_data.py │ ├── __init__.py │ ├── metrics.py │ ├── preprocess_data.py │ ├── process_data.py │ ├── wide_and_deep.py │ └── model_utils │ ├── config.py # 训练配置 │ ├── device_adapter.py # 获取云上id │ ├── local_adapter.py # 获取本地id │ └── moxing_adapter.py # 参数处理 ├── default_config.yaml # 训练参数配置文件 ├── train_and_eval_auto_parallel.py ├── train_and_eval_distribute.py ├── train_and_eval_parameter_server.py ├── train_and_eval.py └── train.py └── export.py ``` ## 脚本参数 ### 训练脚本参数 ``train.py``、``train_and_eval.py``、``train_and_eval_distribute.py``和``train_and_eval_auto_parallel.py``的参数设置相同。 ```python usage: train.py [-h] [--device_target {Ascend,GPU}] [--data_path DATA_PATH] [--epochs EPOCHS] [--full_batch FULL_BATCH] [--batch_size BATCH_SIZE] [--eval_batch_size EVAL_BATCH_SIZE] [--field_size FIELD_SIZE] [--vocab_size VOCAB_SIZE] [--emb_dim EMB_DIM] [--deep_layer_dim DEEP_LAYER_DIM [DEEP_LAYER_DIM ...]] [--deep_layer_act DEEP_LAYER_ACT] [--keep_prob KEEP_PROB] [--dropout_flag DROPOUT_FLAG] [--output_path OUTPUT_PATH] [--ckpt_path CKPT_PATH] [--eval_file_name EVAL_FILE_NAME] [--loss_file_name LOSS_FILE_NAME] [--host_device_mix HOST_DEVICE_MIX] [--dataset_type DATASET_TYPE] [--parameter_server PARAMETER_SERVER] optional arguments: --device_target {Ascend,GPU} device where the code will be implemented. (Default:Ascend) --data_path DATA_PATH This should be set to the same directory given to the data_download's data_dir argument --epochs EPOCHS Total train epochs. (Default:15) --full_batch FULL_BATCH Enable loading the full batch. (Default:False) --batch_size BATCH_SIZE Training batch size.(Default:16000) --eval_batch_size Eval batch size.(Default:16000) --field_size The number of features.(Default:39) --vocab_size The total features of dataset.(Default:200000) --emb_dim The dense embedding dimension of sparse feature.(Default:80) --deep_layer_dim The dimension of all deep layers.(Default:[1024,512,256,128]) --deep_layer_act The activation function of all deep layers.(Default:'relu') --keep_prob The keep rate in dropout layer.(Default:1.0) --dropout_flag Enable dropout.(Default:0) --output_path Deprecated --ckpt_path The location of the checkpoint file. If the checkpoint file is a slice of weight, multiple checkpoint files need to be transferred. Use ';' to separate them and sort them in sequence like "./checkpoints/0.ckpt;./checkpoints/1.ckpt". (Default:./checkpoints/) --eval_file_name Eval output file.(Default:eval.og) --loss_file_name Loss output file.(Default:loss.log) --host_device_mix Enable host device mode or not.(Default:0) --dataset_type The data type of the training files, chosen from tfrecord/mindrecord/hd5.(Default:tfrecord) --parameter_server Open parameter server of not.(Default:0) --vocab_cache_size Enable cache mode.(Default:0) ``` ### 预处理脚本参数 ```python usage: generate_synthetic_data.py [-h] [--output_file OUTPUT_FILE] [--label_dim LABEL_DIM] [--number_examples NUMBER_EXAMPLES] [--dense_dim DENSE_DIM] [--slot_dim SLOT_DIM] [--vocabulary_size VOCABULARY_SIZE] [--random_slot_values RANDOM_SLOT_VALUES] optional arguments: --output_file The output path of the generated file.(Default: ./train.txt) --label_dim The label category. (Default:2) --number_examples The row numbers of the generated file. (Default:4000000) --dense_dim The number of the continue feature.(Default:13) --slot_dim The number of the category features.(Default:26) --vocabulary_size The vocabulary size of the total dataset.(Default:400000000) --random_slot_values 0 or 1. If 1, the id is generated by the random. If 0, the id is set by the row_index mod part_size, where part_size is the vocab size for each slot ``` ```python usage: preprocess_data.py [-h] [--data_path DATA_PATH] [--dense_dim DENSE_DIM] [--slot_dim SLOT_DIM] [--threshold THRESHOLD] [--train_line_count TRAIN_LINE_COUNT] [--skip_id_convert {0,1}] --data_path The path of the data file. --dense_dim The number of your continues fields.(default: 13) --slot_dim The number of your sparse fields, it can also be called category features.(default: 26) --threshold Word frequency below this value will be regarded as OOV. It aims to reduce the vocab size. (default: 100) --train_line_count The number of examples in your dataset. --skip_id_convert 0 or 1. If set 1, the code will skip the id convert, regarding the original id as the final id.(default: 0) ``` ## 准备数据集 ### 处理真实世界数据 1. 下载数据集,并将其存放在某一路径下,例如./data/origin_data。 ```bash mkdir -p data/origin_data && cd data/origin_data wget DATA_LINK tar -zxvf dac.tar.gz ``` > 从[1](#数据集)获取下载链接。 2. 使用此脚本预处理数据。 ```bash python src/preprocess_data.py --data_path=./data/ --dense_dim=13 --slot_dim=26 --threshold=100 --train_line_count=45840617 --skip_id_convert=0 ``` ### 生成和处理合成数据 1. 以下命令将会生成4000万行点击数据,格式如下: > "label\tdense_feature[0]\tdense_feature[1]...\tsparse_feature[0]\tsparse_feature[1]...". ```bash mkdir -p syn_data/origin_data python src/generate_synthetic_data.py --output_file=syn_data/origin_data/train.txt --number_examples=40000000 --dense_dim=13 --slot_dim=51 --vocabulary_size=2000000000 --random_slot_values=0 ``` 2. 预处理生成数据。 ```bash python src/preprocess_data.py --data_path=./syn_data/ --dense_dim=13 --slot_dim=51 --threshold=0 --train_line_count=40000000 --skip_id_convert=1 ``` ## 训练过程 ### 单机训练 运行如下命令训练和评估模型: ```bash python train_and_eval.py --data_path=./data/mindrecord --dataset_type=mindrecord --device_target=Ascend ``` ### 单机训练缓存模式 运行如下命令训练和评估模型: ```bash python train_and_eval.py --data_path=./data/mindrecord --dataset_type=mindrecord --device_target=Ascend --sparse=True --vocab_size=200000 --vocab_cache_size=160000 ``` ### 分布式训练 运行如下命令进行分布式模型训练: ```bash # 训练前配置环境路径 bash run_multinpu_train.sh RANK_SIZE EPOCHS DATASET RANK_TABLE_FILE ``` 运行如下命令进行并行式模型训练: ```bash # 训练前配置环境路径 bash run_auto_parallel_train.sh RANK_SIZE EPOCHS DATASET RANK_TABLE_FILE ``` 运行如下命令进行集群训练模型:''' ```bash # 在集群中部署wide&deep脚本 # CLUSTER_CONFIG为JSON文件,样本存放在script/中。 # 部署后的脚本路径是EXECUTE_PATH bash deploy_cluster.sh CLUSTER_CONFIG_PATH EXECUTE_PATH # 输入EXECUTE_PATH并按照如下步骤执行start_cluster.sh。 # 模式: "host_device_mix" bash start_cluster.sh CLUSTER_CONFIG_PATH EPOCH_SIZE VOCAB_SIZE EMB_DIM DATASET ENV_SH RANK_TABLE_FILE MODE ``` ### 参数服务器 运行如下命令在参数服务器模式下训练和评估模型:''' ```bash # SERVER_NUM为本任务的参数服务器数目。 # SCHED_HOST为调度器的IP地址。 # SCHED_PORT为调度器端口。 # worker的数目应与RANK_SIZE相同。 bash run_parameter_server_train.sh RANK_SIZE EPOCHS DATASET RANK_TABLE_FILE SERVER_NUM SCHED_HOST SCHED_PORT ``` ## 评估过程 运行如下命令评估模型: ```python python eval.py --data_path=./data/mindrecord --dataset_type=mindrecord --device_target=Ascend --ckpt_path=./ckpt/widedeep_train-15_2582.ckpt ``` ## 推理过程 **推理前需参照 [环境变量设置指引](https://gitee.com/mindspore/models/tree/master/utils/ascend310_env_set/README_CN.md) 进行环境变量设置。** ### [导出MindIR](#contents) ```shell python export.py --ckpt_file [CKPT_PATH] --file_name [FILE_NAME] --device_target [DEVICE_TARGET] --file_format [FILE_FORMAT] ``` 参数ckpt_file为必填项, `FILE_FORMAT` 必须在 ["AIR", "MINDIR"]中选择。 ### 在Ascend310执行推理 在执行推理前,mindir文件必须通过`export.py`脚本导出。以下展示了使用minir模型执行推理的示例。 ```shell # Ascend310 推理 bash run_infer_310.sh [MINDIR_PATH] [DATASET_PATH] [DATA_TYPE] [NEED_PREPROCESS] [DEVICE_ID] ``` - `DATA_TYPE` 表示数据类型, 取值范围为 ['tfrecord', 'mindrecord', 'hd5']。 - `NEED_PREPROCESS` 表示数据是否需要预处理,取值范围为 'y' 或者 'n'。 - `DEVICE_ID` 可选,默认值为0。 ### result 推理结果保存在脚本执行的当前路径,你可以在acc.log中看到以下精度计算结果。 ```bash ================================================================================ auc : 0.8080494136248402 ``` # 模型描述 ## 性能 ### 训练性能 | 参数 | Ascend单机 | GPU单机 | 数据并行模式-8卡 | 主机设备模式-8卡 | | ------------------------ | ------------------------------- | ------------------------------- | ------------------------------- | ------------------------------- | | 资源 |Ascend 910;系统 Euler2.8 | Tesla V100-PCIE 32G | Ascend 910;系统 Euler2.8 | Ascend 910;系统 Euler2.8 | | 上传日期 | 2021-07-05 | 2021-07-05 | 2021-07-05 | 2021-07-05 | | MindSpore版本 | 1.3.0 | 1.3.0 | 1.3.0 | 1.3.0 | | 数据集 | [1](#数据集) | [1](#数据集) | [1](#数据集) | [1](#数据集) | | 训练参数 | Epoch=15,<br />batch_size=16000 | Epoch=15,<br />batch_size=16000 | Epoch=15,<br />batch_size=16000 | Epoch=15,<br />batch_size=16000 | | 优化器 | FTRL,Adam | FTRL,Adam | FTRL,Adam | FTRL,Adam | | 损失函数 | Sigmoid交叉熵 | Sigmoid交叉熵 | Sigmoid交叉熵 | Sigmoid交叉熵 | | AUC分数 | 0.80937 | 0.80971 | 0.80862 | 0.80834 | | 速度 | 20.906毫秒/步 | 24.465毫秒/步 | 27.388毫秒/步 | 236.506毫秒/步 | | 损失 | wide:0.433,deep:0.444 | wide:0.444, deep:0.456 | wide:0.437, deep: 0.448 | wide:0.444, deep:0.444 | | 参数(M) | 75.84 | 75.84 | 75.84 | 75.84 | | 推理检查点 | 233MB(.ckpt文件) | 230MB(.ckpt文件) | 233Mb(.ckpt文件) | 233MB(.ckpt文件) | 所有可执行脚本参见[此处](https://gitee.com/mindspore/models/tree/master/official/recommend/wide_and_deep/script)。 说明:GPU的结果是在主版本下测试的。Wide&Deep模型的参数服务模式尚处于开发中。 ### 评估性能 | 参数 | Wide&Deep | | ----------------- | --------------------------- | | 资源 | Ascend 910;系统 Euler2.8 | | 上传日期 | 2021-07-05 | | MindSpore版本 | 1.3.0 | | 数据集 | [1] | | 批次大小 | 16000 | | 输出 | AUC | | 准确率 | AUC=0.809 | ### 极致性能体验 MindSpore从1.1.1版本之后,支持通过开启numa亲和获得极致的性能,需要安装numa库: - ubuntu : sudo apt-get install libnuma-dev - centos/euleros : sudo yum install numactl-devel 1.1.1版本支持设置config的方式开启numa亲和: import mindspore.dataset as de de.config.set_numa_enable(True) 1.2.0版本进一步支持了环境变量开启numa亲和: export DATASET_ENABLE_NUMA=True # 随机情况说明 以下三种随机情况: - 数据集的打乱。 - 模型权重的随机初始化。 - dropout算子。 ## ModelZoo主页 请浏览官网[主页](https://gitee.com/mindspore/models)。