尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
CANN ops-nn 算子库 aclnnSwish 接口详解:Swish 激活算子的两段式调用与源码实现
CANN ops-nn 算子库 aclnnSwish 接口详解Swish 激活算子的两段式调用与源码实现【免费下载链接】ops-nn本项目是CANN提供的神经网络类计算算子库实现网络在NPU上加速计算。项目地址: https://gitcode.com/cann/ops-nn本文以 CANN ops-nn 开源仓库中的 aclnnSwish 接口文档 为核心系统讲解 Swish 激活算子的数学定义、产品支持情况、两段式接口原型、参数约束与返回码并深入 activation/swish 目录下的 op_graph、op_host、op_kernel、op_api 源码与测试用例说明该算子从 Host 侧校验、Tiling 到 NPU 内核计算的完整实现链路。读完本文你将掌握在 CANN 环境下通过 aclnnSwishGetWorkspaceSize / aclnnSwish 两段式接口编写可运行样例的方法并能读懂算子底层按 scale 取值分派的内核实现。一、功能说明与数学原理aclnnSwish 接口实现的算子功能为Swish 激活函数对输入 Tensor 逐元素进行 Swish 函数运算并输出结果 Tensor。其计算公式为$$ s(x) x*\sigma(\beta x) $$$$ \sigma(x) {\frac{1} {1{e}^{-x}}} $$其中 $\sigma(x)$ 为 sigmoid 函数$\beta$ 为可调节参数接口参数 betaOptional / 算子属性 scale。将两式合并即 Swish 的完整表达式$$ s(x) \frac{x}{1 e^{-\beta x}} $$当 $\beta 1$ 时即为标准的 Swish 函数与 PyTorch 的torch.nn.SiLU等价在 swish_proto.h 的算子原型注释中亦注明 Compatible with the Torch operator Swish。$\beta$ 用于控制函数曲线的形状与斜率$\beta$ 越大函数越接近 ReLU 的形态$\beta$ 越小函数越接近线性$\beta 0$ 时退化为 $s(x) x / 2$。从 kernel 侧实现 可以印证该公式的逐元素计算过程内核按矢量寄存器宽度VECTOR_REG_WIDTH 256ULfloat 下vl 64分块循环处理对每个元素依次执行取负Muls乘 -1、乘以 scale、指数运算Exp、加 1Adds与除法Div即dst x / (1 exp(-scale * x))二、产品支持情况根据 aclnnSwish.md 的说明aclnnSwish 接口在各产品上的支持情况如下产品是否支持Ascend 950PR / Ascend 950DT支持Atlas A3 训练系列产品 / Atlas A3 推理系列产品支持Atlas A2 训练系列产品 / Atlas A2 推理系列产品支持Atlas 200I/500 A2 推理产品不支持Atlas 推理系列产品支持Atlas 训练系列产品支持需要注意的是不同产品在数据类型支持范围上存在差异。接口文档中特别注明Atlas 推理系列产品、Atlas 训练系列产品仅支持 FLOAT16、FLOAT两种数据类型不包含 BFLOAT16。这一差异在 aclnn_swish.cpp 源码中得到印证——源码中定义了两张数据类型支持列表// 面向 Atlas 910 系列推理/训练系列产品 static const std::initializer_listop::DataType ASCEND910_DTYPE_SUPPORT_LIST { op::DataType::DT_FLOAT, op::DataType::DT_FLOAT16}; // 面向 Atlas 910B 系列A2 训练/推理系列产品 static const std::initializer_listop::DataType ASCEND910B_DTYPE_SUPPORT_LIST { op::DataType::DT_FLOAT, op::DataType::DT_FLOAT16, op::DataType::DT_BF16};并在校验阶段通过GetDtypeSupportListV2(ASCEND910B_DTYPE_SUPPORT_LIST, ASCEND910_DTYPE_SUPPORT_LIST)依据当前运行平台选择适用的支持列表进而调用CheckDtypeValidActivation完成入参校验。另外从 swish_def.cpp 的算子定义看该算子的 AICore 配置已为ascend950与ascend350两个平台注册对应 config 目录 下 ascend950 / ascend350 两套二进制配置。三、函数原型两段式接口aclnnSwish 属于 CANN 标准的两段式接口——每算子先调用GetWorkspaceSize 段接口获取计算所需 workspace 大小与包含算子计算流程的执行器再调用执行段接口真正下发计算。本文开头引用的链接路径以仓库根目录为基准即 两段式接口说明。接口声明位于 aclnn_swish.h对外导出原型如下aclnnStatus aclnnSwishGetWorkspaceSize( const aclTensor* self, const aclScalar* betaOptional, aclTensor* out, uint64_t* workspaceSize, aclOpExecutor** executor)aclnnStatus aclnnSwish( void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, aclrtStream stream)第一段接口完成入参校验、workspace 大小计算并构建执行器第二段接口接收第一段产出的 workspace、executor 与用户指定的 stream实际执行算子计算。四、aclnnSwishGetWorkspaceSize 参数详解第一段接口共 5 个参数各参数含义、约束与取值范围如下参数名输入/输出描述使用说明数据类型数据格式维度(shape)非连续TensorselfaclTensor*输入表示用于计算激活函数的张量公式中的 x支持空 Tensorself 的 shape 和数据类型与 out 一致BFLOAT16、FLOAT16、FLOATND0-8√betaOptionalaclScalar*输入表示可调节参数用于控制 Swish 函数形状和斜率的标量公式中的 β数据类型需为可转换为 FLOAT 的数据类型参见互转换关系为空指针时接口以 1.0 进行计算----outaclTensor*输出表示 Swish 函数的输出公式中的 s(x)支持空 Tensorout 的 shape 和数据类型与 self 一致BFLOAT16、FLOAT16、FLOATND0-8√workspaceSizeuint64_t*输出返回需要在 Device 侧申请的 workspace 大小-----executoraclOpExecutor**输出返回 op 执行器包含算子计算流程-----需要重点理解的两个输入参数self输入张量公式中的 x支持 0-8 维、ND 格式支持非连续 Tensor接口内部会通过l0op::Contiguous处理非连续输入见 aclnn_swish.cpp。BFLOAT16 的支持需以具体产品为准见上文产品差异。betaOptional公式中的 β。当传空指针时Host 侧实现float scale 1.0f; if (betaOptional ! nullptr) { scale betaOptional-ToFloat(); }即默认以 1.0 计算等价于标准 Swish/SiLU。其数据类型必须能够转换为 FLOAT接口内部通过CanCast(betaOptional-GetDataType(), DataType::DT_FLOAT)检查不满足时返回ACLNN_ERR_PARAM_INVALID。提示在算子 IR 层面swish_def.cpp 与 swish_proto.hβ 对应的是名为scale的 Float 属性this-Attr(scale).AttrType(OPTIONAL).Float(1.0)默认值 1.0两者语义一致。五、返回值与入参校验逻辑两个接口均返回aclnnStatus状态码具体含义参见 aclnn 返回码。第一段接口会完成入参校验出现以下场景时报错返回码错误码描述ACLNN_ERR_PARAM_NULLPTR161001传入的 self 或 out 是空指针ACLNN_ERR_PARAM_INVALID161002self、betaOptional 或 out 的数据类型不在支持的范围内ACLNN_ERR_PARAM_INVALID161002self 和 out 的数据类型不一致ACLNN_ERR_PARAM_INVALID161002self 和 out 的 shape 不一致以上校验在源码CheckParams函数中按序执行见 aclnn_swish.cpp对应关系为CheckNotNull2Tensor(self, out)→ 空指针检查返回ACLNN_ERR_PARAM_NULLPTRCheckDtypeValidActivation(self, out, supportList)→ 数据类型范围与一致性检查CheckDtypeValidBetaToFloat(betaOptional)→ β 类型可转 FLOAT 检查CheckDim(self, out)OP_CHECK_MAX_DIM上限MAX_SUPPORT_DIMS_NUMS与CheckSameShapeNotlimit1In1Out(self, out)→ 维度与 shape 一致性检查。校验通过后若 self 或 out 为空 Tensor接口直接返回*workspaceSize 0并释放执行器否则继续构建l0op::Swish计算图并计算 workspace 大小。六、约束说明确定性计算接口文档中给出的约束如下确定性计算aclnnSwish 为默认确定性实现。即同一输入在相同软硬件环境下多次执行计算结果保持一致不会引入不确定性归约等行为。七、调用示例完整可运行代码以下示例代码摘自接口文档完整展示了从环境初始化、Tensor 构造、两段式接口调用、结果回拷到资源释放的全过程。具体编译和执行过程请参考 编译与运行样例运行前需确保 Device 侧环境已就绪。示例同样可参考仓库中的 examples/test_aclnn_swish.cpp 与 UT 用例 tests/ut/op_api/test_aclnn_swish.cpp。#include iostream #include vector #include acl/acl.h #include aclnnop/aclnn_swish.h #define CHECK_RET(cond, return_expr) \ do { \ if (!(cond)) { \ return_expr; \ } \ } while (0) #define LOG_PRINT(message, ...) \ do { \ printf(message, ##__VA_ARGS__); \ } while (0) int64_t GetShapeSize(const std::vectorint64_t shape) { int64_t shape_size 1; for (auto i : shape) { shape_size * i; } return shape_size; } int Init(int32_t deviceId, aclrtStream* stream) { // 固定写法资源初始化 auto ret aclInit(nullptr); CHECK_RET(ret ACL_SUCCESS, LOG_PRINT(aclInit failed. ERROR: %d\n, ret); return ret); ret aclrtSetDevice(deviceId); CHECK_RET(ret ACL_SUCCESS, LOG_PRINT(aclrtSetDevice failed. ERROR: %d\n, ret); return ret); ret aclrtCreateStream(stream); CHECK_RET(ret ACL_SUCCESS, LOG_PRINT(aclrtCreateStream failed. ERROR: %d\n, ret); return ret); return 0; } template typename T int CreateAclTensor(const std::vectorT hostData, const std::vectorint64_t shape, void** deviceAddr, aclDataType dataType, aclTensor** tensor) { auto size GetShapeSize(shape) * sizeof(T); // 调用aclrtMalloc申请device侧内存 auto ret aclrtMalloc(deviceAddr, size, ACL_MEM_MALLOC_HUGE_FIRST); CHECK_RET(ret ACL_SUCCESS, LOG_PRINT(aclrtMalloc failed. ERROR: %d\n, ret); return ret); // 调用aclrtMemcpy将host侧数据拷贝到device侧内存上 ret aclrtMemcpy(*deviceAddr, size, hostData.data(), size, ACL_MEMCPY_HOST_TO_DEVICE); CHECK_RET(ret ACL_SUCCESS, LOG_PRINT(aclrtMemcpy failed. ERROR: %d\n, ret); return ret); // 计算连续tensor的strides std::vectorint64_t strides(shape.size(), 1); for (int64_t i shape.size() - 2; i 0; i--) { strides[i] shape[i 1] * strides[i 1]; } // 调用aclCreateTensor接口创建aclTensor *tensor aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), *deviceAddr); return 0; } int main() { // 1. 固定写法device/stream初始化, 参考acl API手册 // 根据自己的实际device填写deviceId int32_t deviceId 0; aclrtStream stream; auto ret Init(deviceId, stream); CHECK_RET(ret 0, LOG_PRINT(Init acl failed. ERROR: %d\n, ret); return ret); // 2. 构造输入与输出需要根据API的接口自定义构造 std::vectorint64_t selfShape {4, 2}; std::vectorint64_t outShape {4, 2}; void* selfDeviceAddr nullptr; void* outDeviceAddr nullptr; aclTensor* self nullptr; aclScalar* betaOptional nullptr; aclTensor* out nullptr; std::vectorfloat selfHostData {0, 1, 2, 3, 4, 5, 6, 7}; std::vectorfloat outHostData {0, 0, 0, 0, 0, 0, 0, 0}; float betaValue 1.1f; // 创建self aclTensor ret CreateAclTensor(selfHostData, selfShape, selfDeviceAddr, aclDataType::ACL_FLOAT, self); CHECK_RET(ret ACL_SUCCESS, return ret); // 创建betaOptional aclScalar betaOptional aclCreateScalar(betaValue, aclDataType::ACL_FLOAT); CHECK_RET(betaOptional ! nullptr, return ret); // 创建out aclTensor ret CreateAclTensor(outHostData, outShape, outDeviceAddr, aclDataType::ACL_FLOAT, out); CHECK_RET(ret ACL_SUCCESS, return ret); // 3. 调用CANN算子库API需要修改为具体的API uint64_t workspaceSize 0; aclOpExecutor* executor; // 调用aclnnSwish第一段接口 ret aclnnSwishGetWorkspaceSize(self, betaOptional, out, workspaceSize, executor); CHECK_RET(ret ACL_SUCCESS, LOG_PRINT(aclnnSwishGetWorkspaceSize failed. ERROR: %d\n, ret); return ret); // 根据第一段接口计算出的workspaceSize申请device内存 void* workspaceAddr nullptr; if (workspaceSize 0) { ret aclrtMalloc(workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); CHECK_RET(ret ACL_SUCCESS, LOG_PRINT(allocate workspace failed. ERROR: %d\n, ret); return ret); } // 调用aclnnSwish第二段接口 ret aclnnSwish(workspaceAddr, workspaceSize, executor, stream); CHECK_RET(ret ACL_SUCCESS, LOG_PRINT(aclnnSwish failed. ERROR: %d\n, ret); return ret); // 4. 固定写法同步等待任务执行结束 ret aclrtSynchronizeStream(stream); CHECK_RET(ret ACL_SUCCESS, LOG_PRINT(aclrtSynchronizeStream failed. ERROR: %d\n, ret); return ret); // 5. 获取输出的值将device侧内存上的结果拷贝至host侧需要根据具体API的接口定义修改 auto size GetShapeSize(outShape); std::vectorfloat resultData(size, 0); ret aclrtMemcpy(resultData.data(), resultData.size() * sizeof(resultData[0]), outDeviceAddr, size * sizeof(float), ACL_MEMCPY_DEVICE_TO_HOST); CHECK_RET(ret ACL_SUCCESS, LOG_PRINT(copy result from device to host failed. ERROR: %d\n, ret); return ret); for (int64_t i 0; i size; i) { LOG_PRINT(result[%ld] is: %f\n, i, resultData[i]); } // 6. 释放aclTensor和aclScalar需要根据具体API的接口定义修改 aclDestroyTensor(self); aclDestroyScalar(betaOptional); aclDestroyTensor(out); // 7. 释放device资源需要根据具体API的接口定义修改 aclrtFree(selfDeviceAddr); aclrtFree(outDeviceAddr); if (workspaceSize 0) { aclrtFree(workspaceAddr); } aclrtDestroyStream(stream); aclrtResetDevice(deviceId); aclFinalize(); return 0; }该示例以 β 1.1、输入{0,1,2,3,4,5,6,7}为例按s(x) x / (1 e^{-1.1x})计算。你可以通过修改betaValue为其他值、或将betaOptional置为nullptr等价于 β 1.0来观察不同曲线参数下的输出也可以将selfHostData换成 FLOAT16/BFLOAT16 数据并相应调整CreateAclTensor的dataType参数。八、源码级实现原理8.1 算子原型op_graphswish_proto.h 通过REG_OP(Swish)注册算子原型输入xTensorType 为 DT_FLOAT16、DT_FLOAT、DT_BF16输出y与 x 同类型属性scaleFloat默认 1.0并注明与 PyTorch Swish 算子兼容。8.2 Host 侧算子定义与 Shape 推导op_hostswish_def.cpp 定义了算子输入输出的数据类型FLOAT16/BF16/FLOAT与格式ND并注册了 ascend950、ascend350 两个平台的 AICore 配置支持动态 Shape、动态 Rank、精度降低标志等。swish_infershape.cpp 通过IMPL_OP_INFERSHAPE(Swish).InferShape(Ops::Base::InferShape4Elewise)直接复用逐元素算子的通用 shape 推导即输出 shape 与输入 shape 保持一致——这与接口文档中 self 和 out 的 shape 一致 的约束一一对应。8.3 Tiling 策略按 scale 取值三分派op_host/arch35Tiling 阶段swish_tiling_arch35.cpp先校验输入/输出数据类型必须为 FLOAT16/BF16/FLOAT 且两者一致、shape 必须一致随后在SetAttr中读取 scale 属性缺省 1.0f并根据其取值分为三类模板分派scale 取值枚举attrWork说明-1.0TPL_SCALE_NEG_ONE内核走SwishNegOne专用 DAG0.0TPL_SCALE_ZERO内核走SwishZero专用 DAG其他TPL_SCALE_OTHER内核走通用SwishOtherDAG该分派结果通过GET_TPL_TILING_KEY(schMode, attrWork)编码为 tilingKey 下发给内核内核据此在编译期选择不同的模板实例。此外 Tiling 还会计算 block 维度SetBlockDim与 workspace 大小当前实现为 0并通过TilingPrepareForSwish获取 AIV 核数与 UB 内存大小。8.4 NPU 内核实现op_kernel内核入口 swish_apt.cpp 根据 attrWork 在编译期实例化三类 DAGSwishNegOne、SwishZero、SwishOther均定义于 swish_dag.h每个 DAG 由CopyIn → 计算 → CopyOut组成并使用 L2 内存优化配置SwishNegOnescale -1此时exp(-(-1)*x) exp(x)内核仅需Exp → Adds(1) → Div省去一次乘法SwishZeroscale 0此时s(x) x / (1 e^0) x / 2内核直接退化为Muls(x, 0.5)无需任何指数/除法运算SwishOther其他 scale通用路径执行Muls(x, -1) → Muls(·, scale) → Exp → Adds(1) → Div的完整公式。上述特化体现出算子对编译期常量优化的运用针对 -1 与 0 两个特殊 scale 值生成最简计算图在常见场景如 β0 的退化、β-1 的变体下显著减少指令开销。对于非 float 类型FLOAT16/BFLOAT16内核会先 Cast 到 float 计算再 Cast 回原类型存储以保证中间精度。8.5 Host API 组装op_apiaclnn_swish.cpp 中第一段接口完成校验后将 betaOptional 转为 float 标量并构造l0op::Swish(reshapeSelf, scale, executor)算子节点随后依次处理非连续输入Contiguous、超过最大支持维度的长 TensorReshape/ViewCopy等场景最终通过uniqueExecutor-GetWorkspaceSize()得到 workspace 大小第二段接口aclnnSwish则直接调用通用执行入口CommonOpExecutorRun(workspace, workspaceSize, executor, stream)下发计算。九、测试与验证仓库为 Swish 算子提供了完整的 ST系统测试与 UT单元测试覆盖ST 测试tests/st/aclnnSwish 目录下的atk_aclnnSwish.json用例配置与 executor_aclnnSwish.py。后者以 PyTorch 实现参考公式作为 golden 基准x input_data.kwargs[self].to(torch.float32) scale torch.tensor(input_data.kwargs[betaOptional], dtypetorch.float32) output x / (1 torch.exp(-scale * x))这从测试层面再次印证了本文第一节的数学公式且测试实现同样先转 float32 计算再转回原精度与内核的 Cast 到 float 计算、再 Cast 回原类型 策略一致。UT 测试tests/ut 目录下覆盖 op_apitest_aclnn_swish.cpp、op_hosttest_swish_infershape.cpp、test_swish_tiling.cpp含 arch35 变体与 op_kerneltest_swish_apt.cpp配套 swish_data/gen_data.py 数据生成脚本。二进制配置op_host/config 下 ascend950 / ascend350 的swish_binary.json列出了 x/y 的 dtype 与 ND 格式组合bfloat16 / float16 / float32与算子定义保持严格一致。十、与 aclnnSilu 的关系在 activation/swish/docs 目录下还提供了 aclnnSilu.md 文档。SiLU 本质是 β 固定为 1.0 的 Swishsilu(x) x · sigmoid(x)对应 op_api/aclnn_silu.cpp 中的 aclnnSilu 接口而 aclnnSwish 通过 betaOptional 参数提供了更通用的 β 可调能力。两者共享同一套算子实现swish_def / swish_apt / tiling在需要显式调节激活曲线形态如训练中学习/调度 β时优先选用 aclnnSwish。总结aclnnSwish 是 CANN ops-nn 提供的通用 β 参数 Swish 激活算子接口采用标准的 GetWorkspaceSize Execute 两段式调用模型支持 0-8 维 ND 张量、三种浮点数据类型与空 Tensor并针对 β -1、0 等特殊取值在内核层做了计算图特化优化。通过本文的接口参数说明、完整调用示例与源码实现剖析你可以直接在 CANN 环境中将其接入自己的推理或训练链路也可以此为模板理解 ops-nn 仓库中其他激活算子如 aclnnSilu的接口设计与实现套路。【免费下载链接】ops-nn本项目是CANN提供的神经网络类计算算子库实现网络在NPU上加速计算。项目地址: https://gitcode.com/cann/ops-nn创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

_s 快速上手清单:安装、依赖与首次运行避坑完全指南

_s 快速上手清单:安装、依赖与首次运行避坑完全指南

_s 快速上手清单:安装、依赖与首次运行避坑完全指南 【免费下载链接】_s Inactive project – please visit https://themeshaper.com/block-themes/ to learn more about the future of WordPress themes with Block Themes. 项目地址: https://gitcode.com/gh_m…

📅 2026/9/19 20:13:46
Codex本地AI工具配置指南:模型路由、协议适配与DeepSeek接入

Codex本地AI工具配置指南:模型路由、协议适配与DeepSeek接入

1. 项目概述:Codex 是什么,它解决的是哪类真实问题?Codex 这个词,在当前技术社区里其实存在明显的语义漂移——它不再特指某一家公司的单一产品,而更像一个被泛化使用的功能型代称。从你提供的热搜词和网络热词来看&am…

📅 2026/9/19 20:13:46
5分钟打造免登录HTML入口:单文件实现本地存储与交互

5分钟打造免登录HTML入口:单文件实现本地存储与交互

1. 从零理解“免登录入口”到底在做什么1.1 一个页面为什么需要“免登录”先把概念说清楚。所谓“免登录入口”,本质上就是一个不依赖账号体系、打开就能用的网页。它不需要你输入用户名密码,不需要后端签发令牌,也不依赖任何第三方授权流程。…

📅 2026/9/19 20:13:46
MORE NEWS

更多资讯

📰

智能写作辅助工具测评:提升学术论文写作效率

1. 项目背景与需求解析作为经历过学术写作煎熬的过来人,我深知论文写作过程中资料收集、格式调整、查重降重这些环节有多折磨人。最近帮几位学弟学妹指导毕业论文时,发现2026届学生群体中已经涌现出不少智能写作辅助工具。这些工具宣称能"一键生成符…

📰

Vant Space 间距组件实战指南:横向布局一键拉齐,换行、对齐、源码全解

Vant Space 间距组件实战指南:横向布局一键拉齐,换行、对齐、源码全解 【免费下载链接】vant A lightweight, customizable Vue UI library for mobile web apps. 项目地址: https://gitcode.com/GitHub_Trending/va/vant Vant 的 Space 间距组件…

📰

碳硅共生与RAE引擎:AI与人类对话的新范式

1. 项目背景与核心概念解析"对话本体论:碳硅共生与RAE引擎的存在论根源"这个标题涉及三个核心概念:对话本体论、碳硅共生、RAE引擎。这三个概念共同构成了一个探讨人工智能与人类关系的前沿理论框架。对话本体论(Dialogical Ontolo…

📰

self-llm 教程实战:用 SGLang 部署 MiniMax-M3,完成 512K 长上下文推理、图片输入与工具调用

self-llm 教程实战:用 SGLang 部署 MiniMax-M3,完成 512K 长上下文推理、图片输入与工具调用 【免费下载链接】self-llm 《开源大模型食用指南》针对中国宝宝量身打造的基于Linux环境快速微调(全参数/Lora)、部署国内外开源大模型…

📰

AutoDev Review Agent 跑 Issues Analysis,Base URL 填 TaoToken

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

Elsevier投稿模板Word版使用指南:从样式检查到提交前体检

简介:这份爱思唯尔(Elsevier)期刊投稿Word模板,专为准备向爱思唯尔旗下期刊投稿的科研作者和研究生设计,用于快速产出符合出版社要求的论文初稿。模板覆盖标题页、作者信息、摘要、关键词、正文、通讯作者标注等完整结…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬