华为云用户手册

  • 响应参数 状态码: 200 表3 响应Body参数 参数 参数类型 描述 status String 状态 error Object 错误 result result object 结果 表4 result 参数 参数类型 描述 id String id build_project_id String 构建工程ID,唯一对应codeci_job_id build_record_id String 构建记录ID parent_record_id String 父构建记录ID devcloud_project_id String 项目ID codeci_job_id String codeci任务ID,唯一对应build_project_id user_id String 用户ID build_no Integer 构建编号 daily_build_num String 每日构建编号,每日从1开始 execution_id String 八爪鱼任务ID repo_name String 仓库名称 repo_id String 仓库id branch String 仓库分支 tag String 仓库tag commit String 仓库commit ID commit_message String 仓库commit提交信息 commit_create_time String commit创建时间 trigger_type String 触发类型 build_type String 构建类型 status String 构建状态 domain_id String 租户ID create_time String 任务创建时间 schedule_time String 构建下发耗时 queued_time String 构建排队耗时 start_time String 开始构建时间 runnable_time String 八爪鱼真正开始构建时间 finish_time String 构建结束时间 duration Integer 构建时长 record_status String record状态 use_private_slave Integer 是否使用自定义执行机 region String 租户所在region err_msg String 错误信息 build_config_type String 构建配置类型,YAML或ACTION 状态码: 400 表5 响应Body参数 参数 参数类型 描述 error_code String 错误码 error_msg String 错误描述 状态码: 401 表6 响应Body参数 参数 参数类型 描述 error_code String 错误码 error_msg String 错误描述 状态码: 403 表7 响应Body参数 参数 参数类型 描述 error_code String 错误码 error_msg String 错误描述 状态码: 404 表8 响应Body参数 参数 参数类型 描述 error_code String 错误码 error_msg String 错误描述 状态码: 500 表9 响应Body参数 参数 参数类型 描述 error_code String 错误码 error_msg String 错误描述
  • 响应示例 状态码: 200 处理成功返回。 { "data_list" : [ { "time" : "2020-06-04T07:00:00Z", "value" : 0 }, { "time" : "2020-06-04T07:05:00Z", "value" : 325 } ] } 状态码: 400 参数错误。 { "error_code" : "LIVE.100011001", "error_msg" : "Invalid request parameter: domain" }
  • 响应参数 状态码: 200 表4 响应Header参数 参数 参数类型 描述 X-Request-Id String 请求的唯一标识。 表5 响应Body参数 参数 参数类型 描述 data_list Array of StreamCountData objects 采样数据列表。 表6 StreamCountData 参数 参数类型 描述 value Integer 采样时间点的推流路数。 time String 采样时间。日期格式按照ISO8601表示法,并使用UTC时间。 格式为:YYYY-MM-DDThh:mm:ssZ。 状态码: 400 表7 响应Header参数 参数 参数类型 描述 X-Request-Id String 请求的唯一标识。 表8 响应Body参数 参数 参数类型 描述 error_code String 错误码。 error_msg String 错误描述。
  • 请求参数 表3 请求Header参数 参数 是否必选 参数类型 描述 X-Auth-Token 否 String 用户Token。使用Token鉴权方式时必选。 通过调用 IAM 服务获取用户Token接口获取(响应消息头中X-Subject-Token的值)。 Authorization 否 String 使用AK/SK方式认证时必选,携带的鉴权信息。 X-Sdk-Date 否 String 使用AK/SK方式认证时必选,请求的发生时间。 X-Project-Id 否 String 使用AK/SK方式认证时必选,携带项目ID信息, 与路径参数中的项目ID相同。
  • URI GET /v2/{project_id}/stats/stream-count 表1 路径参数 参数 是否必选 参数类型 描述 project_id 是 String 项目ID,获取方法请参考获取项目ID。 表2 Query参数 参数 是否必选 参数类型 描述 publish_domains 是 Array 推流域名列表,最多支持查询100个域名, 多个域名 以逗号分隔,若查询多个域名,则返回的是多个域名合并数据。 start_time 否 String 起始时间。日期格式按照ISO8601表示法,并使用UTC时间。 格式为:YYYY-MM-DDThh:mm:ssZ。最大查询跨度31天,最大查询周期1年。 若参数为空,默认查询7天数据。 end_time 否 String 结束时间。日期格式按照ISO8601表示法,并使用UTC时间。 格式为:YYYY-MM-DDThh:mm:ssZ。 若参数为空,默认为当前时间,最大查询跨度31天, 最大查询跨度31天,最大查询周期1年。
  • 请求消息体(可选) 该部分可选。请求消息体通常以结构化格式(如JSON或XML)发出,与请求消息头中Content-Type对应,传递除请求消息头之外的内容。若请求消息体中的参数支持中文,则中文字符必须为UTF-8编码。 每个接口的请求消息体内容不同,也并不是每个接口都需要有请求消息体(或者说消息体为空),GET、DELETE操作类型的接口就不需要消息体,消息体具体内容需要根据具体接口而定。 对于获取用户Token接口,您可以从接口的请求部分看到所需的请求参数及参数说明。将消息体加入后的请求如下所示,加粗的斜体字段需要根据实际值填写,其中username为用户名,domainname为用户所属的账号名称,********为用户登录密码,xxxxxxxxxxxxxxxxxx为project的名称,如“cn-north-1”,您可以从地区和终端节点获取。 scope参数定义了Token的作用域,下面示例中获取的Token仅能访问project下的资源。您还可以设置Token的作用域为某个账号下所有资源或账号的某个project下的资源,详细定义请参见获取用户Token。 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 POST https://iam.cn-north-1.myhuaweicloud.com/v3/auth/tokens Content-Type: application/json { "auth": { "identity": { "methods": [ "password" ], "password": { "user": { "name": "username", "password": "********", "domain": { "name": "domainname" } } } }, "scope": { "project": { "name": "xxxxxxxxxxxxxxxxxx" } } } } 到这里为止这个请求需要的内容就具备齐全了,您可以使用curl、Postman或直接编写代码等方式发送请求调用API。对于获取用户Token接口,返回的响应消息头中的“x-subject-token”就是需要获取的用户Token。有了Token之后,您就可以使用Token认证调用其他API。
  • 请求方法 HTTP请求方法(也称为操作或动词),它告诉服务您正在请求什么类型的操作。 表2 HTTP方法 方法 说明 GET 请求服务器返回指定资源。 PUT 请求服务器更新指定资源。 POST 请求服务器新增资源或执行特殊操作。 DELETE 请求服务器删除指定资源,如删除对象等。 HEAD 请求服务器资源头部。 PATCH 请求服务器更新资源的部分内容。 当资源不存在的时候,PATCH可能会去创建一个新的资源。 在获取用户Token的URI部分,您可以看到其请求方法为“POST”,则其请求为: 1 POST https://iam.cn-north-1.myhuaweicloud.com/v3/auth/tokens
  • 请求消息头 附加请求头字段,如指定的URI和HTTP方法所要求的字段。例如定义消息体类型的请求头“Content-Type”,请求鉴权信息等。 详细的公共请求消息头字段请参见表3。 表3 公共请求消息头 名称 描述 是否必选 示例 Host 请求的服务器信息,从服务API的URL中获取。值为hostname[:port]。端口缺省时使用默认的端口,https的默认端口为443。 否 使用AK/SK认证时该字段必选。 code.test.com or code.test.com:443 Content-Type 消息体的类型(格式)。推荐用户使用默认值application/json,有其他取值时会在具体接口中专门说明。 是 application/json Content-Length 请求body长度,单位为Byte。 否 3495 X-Project-Id project id,项目编号。请参考获取项目ID章节获取项目编号。 否 如果是专属云场景采用AK/SK认证方式的接口请求,或者多project场景采用AK/SK认证的接口请求,则该字段必选。 e9993fc787d94b6c886cbaa340f9c0f4 X-Auth-Token 用户Token。 用户Token也就是调用获取用户Token接口的响应值,该接口是唯一不需要认证的接口。 请求响应成功后在响应消息头(Headers)中包含的“X-Subject-Token”的值即为Token值。 否 使用Token认证时该字段必选。 注:以下仅为Token示例片段。 MIIPAgYJKoZIhvcNAQcCo...ggg1BBIINPXsidG9rZ API同时支持使用AK/SK认证,AK/SK认证使用SDK对请求进行签名,签名过程会自动往请求中添加Authorization(签名认证信息)和X-Sdk-Date(请求发送的时间)请求头。 AK/SK认证的详细说明请参见认证鉴权的“AK/SK认证”。 对于获取用户Token接口,由于不需要认证,所以只添加“Content-Type”即可,添加消息头后的请求如下所示。 1 2 POST https://iam.cn-north-1.myhuaweicloud.com/v3/auth/tokens Content-Type: application/json
  • 请求URI 请求URI由如下部分组成: {URI-scheme}://{Endpoint}/{resource-path}?{query-string} 尽管请求URI包含在请求消息头中,但大多数语言或框架都要求您从请求消息中单独传递它,所以在此单独强调。 表1 URI中的参数说明 参数 描述 URI-scheme 表示用于传输请求的协议,当前所有API均采用HTTPS协议。 Endpoint 指定承载REST服务端点的服务器域名或IP,不同服务不同区域的Endpoint不同,您可以从地区和终端节点获取。 例如IAM服务在“华北-北京四”区域的Endpoint为“iam.cn-north-4.myhuaweicloud.com”。 resource-path 资源路径,即API访问路径。从具体API的URI模块获取,例如“获取用户Token”API的resource-path为“/v3/auth/tokens”。 query-string 查询参数,是可选部分,并不是每个API都有查询参数。查询参数前面需要带一个“?”,形式为“参数名=参数取值”,例如“?limit=10”,表示查询不超过10条数据。 例如您需要获取IAM在“华北-北京四”区域的Token,则需使用“华北-北京四”区域的Endpoint(iam.cn-north-4.myhuaweicloud.com),并在获取用户Token的URI部分找到resource-path(/v3/auth/tokens),拼接起来如下所示。 1 https://iam.cn-north-4.myhuaweicloud.com/v3/auth/tokens 图1 URI示意图 为方便查看,在每个具体API的URI部分,只给出resource-path部分,并将请求方法写在一起。这是因为URI-scheme都是HTTPS,而Endpoint在同一个区域也相同,所以简洁起见将这两部分省略。
  • AK/SK认证 AK/SK签名认证方式仅支持消息体大小在12MB以内,12MB以上的请求请使用Token认证。 AK/SK认证就是使用AK/SK对请求进行签名,在请求时将签名信息添加到消息头,从而通过身份认证。 AK(Access Key ID):访问密钥ID。与私有访问密钥关联的唯一标识符;访问密钥ID和私有访问密钥一起使用,对请求进行加密签名。 SK(Secret Access Key):私有访问密钥。与访问密钥ID结合使用,对请求进行加密签名,可标识发送方,并防止请求被修改。 使用AK/SK认证时,您可以基于签名算法使用AK/SK对请求进行签名,也可以使用专门的签名SDK对请求进行签名。详细的签名方法和SDK使用方法请参见API签名指南。 签名SDK只提供签名功能,与服务提供的SDK不同,使用时请注意。
  • Token认证 Token的有效期为24小时,需要使用一个Token鉴权时,可以先缓存起来,避免频繁调用。 Token在计算机系统中代表令牌(临时)的意思,拥有Token就代表拥有某种权限。Token认证就是在调用API的时候将Token加到请求消息头中,从而通过身份认证,获得操作API的权限。Token可通过调用获取用户Token接口获取。 调用本服务API需要项目级别的Token,即调用获取用户Token接口时,请求body中auth.scope的取值需要选择project,如下所示。 { "auth": { "identity": { "methods": [ "password" ], "password": { "user": { "name": "username", //IAM用户名 "password": "********", //IAM用户密码 "domain": { "name": "domainname" //IAM用户所属账号名 } } } }, "scope": { "project": { "name": "xxxxxxxx" //项目名称 } } } } 获取Token 后,再调用其他接口时,您需要在请求消息头中添加“X-Auth-Token”,其值即为Token。例如Token值为“ABCDEFJ....”,则调用接口时将“X-Auth-Token: ABCDEFJ....”加到请求消息头即可,如下所示。 1 2 3 POST https://iam.cn-north-1.myhuaweicloud.com/v3/auth/projects Content-Type: application/json X-Auth-Token: ABCDEFJ.... 您还可以通过这个视频教程了解如何使用Token认证:https://bbs.huaweicloud.com/videos/101333。
  • 调用API获取项目ID 您还能通过调用查询指定条件下的项目信息API获取项目ID。 获取项目ID的接口为“GET https://{Endpoint}/v3/projects/”,其中{Endpoint}为IAM的终端节点,可以从地区和终端节点获取。接口的认证鉴权请参见认证鉴权。 响应示例如下,其中projects下的“id”即为项目ID。 { "projects": [ { "domain_id": "65382450e8f64ac0870cd180d14e684b", "is_domain": false, "parent_id": "65382450e8f64ac0870cd180d14e684b", "name": "region01", "description": "", "links": { "next": null, "previous": null, "self": "https://www.example.com/v3/projects/a4a5d4098fb4474fa22cd05f897d6b99" }, "id": "a4a5d4098fb4474fa22cd05f897d6b99", "enabled": true } ], "links": { "next": null, "previous": null, "self": "https://www.example.com/v3/projects" } }
  • 错误码 当您调用API时,如果遇到“APIGW”开头的错误码,请参见API网关错误码进行处理。 状态码 错误码 错误信息 描述 处理措施 400 LIVE.100011001 Invalid request parameter. 请求参数非法。 可能缺少必要参数,或者参数值格式不正确,具体错误信息请查看错误描述 error_detail 字段。 400 LIVE.100011004 The protocol is not supported. The API only supports the HTTPS protocol. 协议不支持,当前API仅支持https协议,不支持http协议 请使用https协议 400 LIVE.100011006 This API is not supported in this version or is in the maintenance state. 本版本内不支持此接口或该接口处于维护状态 请稍后重试或者联系客服人员帮忙解决 400 LIVE.100011008 The API is in the maintenance state. 当前接口处于停服维护状态 请稍后重试,或提交工单,申请技术客服协助解决问题 400 LIVE.100011009 The requested user does not exist. 请求用户不存在 请确认用户的输入信息是否正确 400 LIVE.100011011 The method specified in the request is not supported. 处理禁用请求中指定的方法 确认请求的http方法是否正确 400 LIVE.100011012 Unsupported media type. 不支持的媒体类型异常 提交工单,申请技术客服协助解决问题 400 LIVE.100011013 You have not completed real-name authentication. 用户没有实名认证 请先进行实名认证 400 LIVE.100011022 LIVE.Record task exist. 录制任务已存在 停止录制命令下发之后,再次对相同流下发开始录制命令,必须间隔10秒以上。 400 LIVE.103011018 The resource already exists. 资源已存在 确认要操作的资源是否已经存在 400 LIVE.103011020 The maximum number of domain names has been reached. 域名数量超过配额 超过租户最大域名添加上限,删除不必要的域名再添加;如确有必要超额添加,请提交工单申请技术客服审核 400 LIVE.103011021 Failed to access the database. 访问DB失败 提交工单,申请技术客服协助解决问题 400 LIVE.103011022 This operation is not allowed in the current state. 当前域名的状态不支持此操作 确认域名当前状态:非停用状态不可修改、删除 400 LIVE.103011024 The ICP number does not exist. 域名对应的ICP编号不存在 请检查ICP编号是否正确 400 LIVE.103011025 The approved ICP number cannot be modified. 审核通过的许可证号不允许修改 ICP编号在首次添加审核通过后不允许修改,如有修改必要请提交工单,申请技术客服协助解决问题 400 LIVE.103011026 The domain name is in the blacklist. 域名在黑名单网站中 更换合法注册的域名进行操作 400 LIVE.103011027 The domain name is in the blacklist. 域名在非法接入黑名单中 更换合法注册的域名进行操作 400 LIVE.103011029 The domain name is in gray configuration. 此域名存在灰度配置,配置下发失败 提交工单,申请技术客服协助解决问题 400 LIVE.103011030 This domain name has customized configuration. 此域名存在定制化配置,配置下发失败 提交工单,申请技术客服协助解决问题 401 LIVE.100011002 Identity authentication failed. 身份认证失败。 一般是由于签名计算错误导致的,请参考文档中签名方法部分。 401 LIVE.100011003 You do not have permission to access the API. 未授权访问接口 请联系主帐号管理员开通接口权限 401 LIVE.100011014 Your account is not allowed to access the service, because it is frozen, deleted, or has insufficient balance. 用户当前状态不允许访问,比如冻结、删除、余额不足。 华为云账户异常,请确认是否处于欠费冻结或停用状态 401 LIVE.100011015 Project ID verification failed. projectID校验失败 确认请求中的项目ID及请求头部 403 LIVE.103011016 Invalid request content. 请求内容非法 请求参数不合规范 404 LIVE.103011019 The resource does not exist. 资源不存在 确认要操作的资源是否存在或租户账号信息是否正确 500 LIVE.100011000 Internal communication error. 内部服务器通信异常 提交工单,申请技术客服协助解决问题 500 LIVE.100011005 Internal server error. 服务器内部出现错误 请稍后重试或者联系客服人员帮忙解决 500 LIVE.100011007 The number of concurrent API requests exceeds the upper limit. 接口请求超过并发限制 提交工单,申请技术客服协助解决问题 500 LIVE.103011017 Failed to synchronize data to CDN. 同步数据到CDN失败 确认域名是否已经备案并向有关部门申请取得许可;如果确认域名合法依然失败,请提交工单,申请技术客服协助解决问题 500 LIVE.103011023 Failed to synchronize the domain name to GSLB. 同步域名到GSLB失败 提交工单,申请技术客服协助解决问题 500 LIVE.103011028 Failed to synchronize the domain name to DNS. 同步域名到DNS失败 提交工单,申请技术客服协助解决问题 父主题: 附录
  • 响应示例 状态码: 200 查询直播拉流回源配置成功 { "play_domain" : "pull.example.test.com", "source_type" : "domain", "sources" : [ "example1.test.com", "example2.test.com" ], "scheme" : "http", "additional_args" : { "key1" : "value1", "key2" : "value2" } } 状态码: 400 参数错误 { "error_code" : "LIVE.100011001", "error_msg" : "Request Illegal" }
  • 请求参数 表3 请求Header参数 参数 是否必选 参数类型 描述 X-Auth-Token 否 String 用户Token,使用Token鉴权方式时必填。通过调用IAM服务获取用户Token接口获取(响应消息头中X-Subject-Token的值)。 Authorization 否 String 使用AK/SK方式认证时必填,携带的鉴权信息。 X-Sdk-Date 否 String 使用AK/SK方式认证时必填,请求的发生时间。 X-Project-Id 否 String 使用AK/SK方式认证时必填,携带项目ID信息。
  • 请求参数 表2 请求Header参数 参数 是否必选 参数类型 描述 X-Auth-Token 否 String 用户Token,使用Token鉴权方式时必填。通过调用IAM服务获取用户Token接口获取(响应消息头中X-Subject-Token的值)。 Authorization 否 String 使用AK/SK方式认证时必填,携带的鉴权信息。 X-Sdk-Date 否 String 使用AK/SK方式认证时必填,请求的发生时间。 X-Project-Id 否 String 使用AK/SK方式认证时必填,携带项目ID信息。 表3 请求Body参数 参数 是否必选 参数类型 描述 play_domain 是 String 播放域名 app 否 String 应用名称,默认为live delay 是 Integer 延时时间,单位:ms 2000(低) 4000(中) 6000(高)
  • 响应示例 状态码: 200 查询播放域名延时配置成功 { "play_domain" : "pull.example.test.com", "delay_config" : [ { "app" : "live", "delay" : 6000 } ] } 状态码: 400 参数错误 { "error_code" : "LIVE.100011001", "error_msg" : "Request Illegal" }
  • 响应参数 状态码: 200 表4 响应Body参数 参数 参数类型 描述 play_domain String 播放域名 delay_config Array of DelayConfig objects 直播延时配置 表5 DelayConfig 参数 参数类型 描述 app String 应用名,默认为live delay Integer 延时时间,单位:ms 2000(低) 4000(中) 6000(高) 状态码: 400 表6 响应Body参数 参数 参数类型 描述 error_code String 错误码 error_msg String 错误描述
  • 请求参数 表3 请求Header参数 参数 是否必选 参数类型 描述 X-Auth-Token 否 String 用户Token,使用Token鉴权方式时必填。通过调用IAM服务获取用户Token接口获取(响应消息头中X-Subject-Token的值)。 Authorization 否 String 使用AK/SK方式认证时必填,携带的鉴权信息。 X-Sdk-Date 否 String 使用AK/SK方式认证时必填,请求的发生时间。 X-Project-Id 否 String 使用AK/SK方式认证时必填,携带项目ID信息。
  • 响应示例 状态码: 200 查询地域限制配置列表成功 { "play_domain" : "play.example.huawei.com", "apps" : [ { "app" : "live,", "area_whitelist" : [ "CN-IN", "CN-HK", "CN-MO", "CN-TW", "BR" ] } ] } 状态码: 400 查询地域限制配置列表失败 { "error_code" : "LIVE.100011001", "error_msg" : "Request Illegal" }
  • 响应参数 状态码: 200 表4 响应Header参数 参数 参数类型 描述 X-Request-Id String 此字段携带请求ID号,以便任务跟踪。格式为:request_id-timestamp-hostname(request_id在服务器端生成UUID,timestamp为当前时间戳,hostname为处理当前接口的服务器名称) 表5 响应Body参数 参数 参数类型 描述 play_domain String 直播播放域名 apps Array of GeoBlockingConfigInfo objects 应用列表 表6 GeoBlockingConfigInfo 参数 参数类型 描述 app String 应用名 area_whitelist Array of strings 限制区域列表, 空列表表示不限制。 国家/地区代码,2位字母大写,为空表示不限制。代码格式参阅ISO 3166-1 alpha-2 状态码: 400 表7 响应Header参数 参数 参数类型 描述 X-Request-Id String 此字段携带请求ID号,以便任务跟踪。格式为:request_id-timestamp-hostname(request_id在服务器端生成UUID,timestamp为当前时间戳,hostname为处理当前接口的服务器名称) 表8 响应Body参数 参数 参数类型 描述 error_code String 错误码 error_msg String 错误描述
  • 请求参数 表3 请求Header参数 参数 是否必选 参数类型 描述 X-Auth-Token 否 String 用户Token,使用Token鉴权方式时必填。通过调用IAM服务获取用户Token接口获取(响应消息头中X-Subject-Token的值)。 Authorization 否 String 使用AK/SK方式认证时必填,携带的鉴权信息。 X-Sdk-Date 否 String 使用AK/SK方式认证时必填,请求的发生时间。 X-Project-Id 否 String 使用AK/SK方式认证时必填,携带项目ID信息。
  • 请求示例 修改直播拉流回源配置。 PUT https://{endpoint}/v1/{project_id}/domain/pull-sources { "play_domain" : "pull.example.test.com", "source_type" : "domain", "sources" : [ "example1.test.com", "example2.test.com" ], "scheme" : "http", "additional_args" : { "key1" : "value1", "key2" : "value2" } }
  • 响应参数 状态码: 200 表5 响应Header参数 参数 参数类型 描述 X-Request-Id String 此字段携带请求ID号,以便任务跟踪。格式为:request_id-timestamp-hostname(request_id在服务器端生成UUID,timestamp为当前时间戳,hostname为处理当前接口的服务器名称) 状态码: 400 表6 响应Header参数 参数 参数类型 描述 X-Request-Id String 此字段携带请求ID号,以便任务跟踪。格式为:request_id-timestamp-hostname(request_id在服务器端生成UUID,timestamp为当前时间戳,hostname为处理当前接口的服务器名称) 表7 响应Body参数 参数 参数类型 描述 error_code String 错误码 error_msg String 错误描述
  • 请求参数 表3 请求Header参数 参数 是否必选 参数类型 描述 X-Auth-Token 否 String 用户Token,使用Token鉴权方式时必填。通过调用IAM服务获取用户Token接口获取(响应消息头中X-Subject-Token的值)。 Authorization 否 String 使用AK/SK方式认证时必填,携带的鉴权信息。 X-Sdk-Date 否 String 使用AK/SK方式认证时必填,请求的发生时间。 X-Project-Id 否 String 使用AK/SK方式认证时必填,携带项目ID信息。 表4 请求Body参数 参数 是否必选 参数类型 描述 app 是 String 应用名 area_whitelist 否 Array of strings 限制区域列表, 空列表表示不限制。 国家/地区代码,2位字母大写,为空表示不限制。代码格式参阅ISO 3166-1 alpha-2
  • 训练代码 以下代码中以“### 分布式改造,... ###”注释的代码即为多节点分布式训练需要适配的代码改造点。 不对示例代码进行任何修改,适配数据路径后即可在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+
  • 数据集 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'后可直接进行训练任务,无需加载数据。
  • setExternalAudioFrameOutput setExternalAudioFrameOutput(localEnable:boolean, remoteEnable:boolean): number 【功能说明】 开启音频自渲染。 【请求参数】 localEnable:必选,boolean类型,开启本地音频自渲染,默认sdk渲染。 remoteEnable:必选,boolean类型,开启远端音频自渲染,默认sdk渲染。 【返回参数】
  • onDownStreamStatusChangeNotify void onDownStreamStatusChangeNotify(const HRTCDownStreamStatusChangeNotify* downStreamInfos, unsigned int count) 【功能说明】 全量上报下行主流状态变化通知,接收端探测网络变化,分配给每路下行流,如果有下行流因为带宽不足被停掉或者带宽恢复而恢复,则上报给产品。 【回调参数】 downStreamInfos:下行流信息,具体请参见HRTCDownStreamStatusChangeNotify。 count:下行流数量。
  • onRemoteShareStatusChangeNotify void onRemoteShareStatusChangeNotify(const char* userId, bool isRecving) 【功能说明】 上报下行辅流状态变化通知,接收端探测网络变化,分配给下行辅流,如果有辅流因为带宽不足被停掉或者带宽恢复而恢复,则上报给产品。 【回调参数】 userId:下行辅流对应的用户ID。 isRecving:是否接受。
共100000条