首页
/ 深入拆解 webpack Harmony(ES Module)打包机制:从 examples/harmony 看 import/export 编译与 import() 代码分割

深入拆解 webpack Harmony(ES Module)打包机制:从 examples/harmony 看 import/export 编译与 import() 代码分割

2026-09-07 22:48:04作者:卓炯娓

本篇文章以当前仓库中 examples/harmony 示例 为核心线索,逐行分析一个仅由原生 ES Module(webpack 语境下的 Harmony 模块)组成的微型应用,是如何被 webpack 编译成可运行的 bundle 的。你将看到 import/export 被翻译成模块包装函数与 __webpack_require__ 调用的全过程,import() 动态导入如何自动触发代码分割并生成异步 chunk,以及 __webpack_require__.e/.u/.l/.f.j 与 JSONP 回调构成的按需加载运行时。读完本文,你能从产物层面真正读懂 ES Module 在 webpack 中的编译形态,为理解 tree shaking、模块联邦、懒加载等进阶能力打下基础。

示例全景:一个只有 ES Module 的最小应用

examples/harmony 是 webpack 官方 examples 目录中演示 Harmony 模块(即 ES2015+ 模块) 的基准示例。在 webpack 的历史命名中,harmony 正是 ECMAScript 模块(ESM / ES Module)的代称——webpack 的 harmony 相关解析插件、依赖类与产物注释(如 /* harmony export */)都沿用了这一叫法。相关示例被集中收录在 examples/README.md 的 "Harmony" 分组下。

整个示例只包含 4 个源文件,形成一条清晰的依赖链:

文件 模块角色 说明
example.js 入口模块 命名导入(带别名)、同步调用、import() 动态加载
increment.js 中间模块 export function 导出,并从 math.js 导入 add
math.js 叶子模块 export function add,接受任意数量参数求和
async-loaded.js 异步模块 export var answer = 42,会被切分为独立 chunk

入口模块 example.js

example.js 展示了 ES Module 的两种典型消费方式:

import { increment as inc } from './increment';
var a = 1;
inc(a); // 2

// async loading
import("./async-loaded").then(function(asyncLoaded) {
	console.log(asyncLoaded);
});
  • import { increment as inc }带别名的命名导入,编译产物中会保留“引用原绑定”的语义(见后文产物中的 increment 处理);
  • inc(a) 是对 Harmony 模块导出函数的同步调用,在产物中会被改写为 (0,_increment__WEBPACK_IMPORTED_MODULE_0__.increment)(a),这样调用时 this 不会被意外指向模块命名空间;
  • import("./async-loaded")动态导入表达式,webpack 会把它识别为一个新的依赖块,自动切分出独立的异步 chunk,而不是把代码塞进主 bundle。

中间模块 increment.js

increment.js 体现了 ES Module 的“再导入 + 再导出”组合:

import { add } from './math';
export function increment(val) {
    return add(val, 1);
};

increment 本身导出一个命名函数,函数体内调用的 add 来自对 math.js 的命名导入。这类“导入后调用其他模块导出”的模式是 webpack 产物中最常见的编译对象。

叶子模块 math.js

math.js 是依赖链的末端:

export function add() {
	var sum = 0, i = 0, args = arguments, l = args.length;
	while (i < l) {
		sum += args[i++];
	}
	return sum;
}

注意 add 故意写成变参求和的传统函数,而不是固定两个参数,目的是让示例在 inc 任意取值时都能正确返回 val + 1(例如 add(1, 1) === 2)。

被切分出去的异步模块 async-loaded.js

async-loaded.js 只有一行导出:

export var answer = 42;

正因为它只被 import() 引用,webpack 会把它编排进一个按需加载的 chunk(本示例中即 655.output.js),而不是打进主 output.js

产物体检:bundle 的整体骨架

在示例目录下以 example.js 为入口执行构建后,产物落在 dist/,本文引用的 examples/harmony/README.md 展示了完整的 dist/output.js。整个 bundle 由三个逻辑层构成:

  1. 模块表 __webpack_modules__:一个以 module id 为下标的数组,每个元素是一个“模块包装函数”;
  2. webpack 运行时(runtime):负责模块缓存、require、命名空间标记、属性 getter、chunk 加载等基础设施的 IIFE;
  3. 入口执行代码:被包裹在独立 IIFE 中的入口模块逻辑。

外层再用一个 (() => { ... })() 自执行函数整体包裹,形成"webpackBootstrap"结构:

/******/ (() => { // webpackBootstrap
/******/ 	"use strict";
/******/ 	var __webpack_modules__ = ([
/* 0 */,
/* 1 */ ...
/* 2 */ ...
/******/ 	]);

模块表:每个 ES Module 都变成“包装函数”

模块表把每个模块编译成一个 (module, module.exports, __webpack_require__) => { ... } 形式的函数,数组下标即 module id。id 0 是占位(留给入口),id 1 是 increment.js,id 2 是 math.jsasync-loaded.js 则随异步 chunk 携带(本示例中为 id 3)。

increment.js 为例,其编译形态如下:

/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   increment: () => (/* binding */ increment)
/* harmony export */ });
/* harmony import */ var _math__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./math */ 2);

function increment(val) {
    return (0,_math__WEBPACK_IMPORTED_MODULE_0__.add)(val, 1);
};

这里可以提炼出 Harmony 模块编译的三条核心规则:

  • __webpack_require__.r 标记命名空间:把当前模块的 exports 标记为 ES Module(打上 Symbol.toStringTag__esModule);
  • __webpack_require__.d 定义导出 getter:ES Module 的导出是只读绑定,因此不能用简单赋值,而是通过 Object.defineProperty 定义 getter(/* binding */ increment 说明该 getter 直接绑定到函数声明);
  • import 被降级为 __webpack_require__ 调用import { add } from './math' 变成 var _math__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./math */ 2)(0, ...) 前缀确保以 undefined 的 this 调用被导入函数。

math.js 的编译形态与之一致:

/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   add: () => (/* binding */ add)
/* harmony export */ });
function add() {
	var sum = 0, i = 0, args = arguments, l = args.length;
	while (i < l) {
		sum += args[i++];
	}
	return sum;
}

模块顶部的“导出信息注释”

每个模块包装函数上方都有一段 webpack 生成的注释,例如:

/*! namespace exports */
/*! export add [provided] [no usage info] [missing usage info prevents renaming] */
/*! other exports [not provided] [no usage info] */
/*! runtime requirements: __webpack_require__.r, __webpack_exports__, __webpack_require__.d, __webpack_require__.* */

这些注释并非装饰,而是模块导出信息(ExportsInfo)分析结果的直接投影,其中:

  • namespace exports:该模块按 ES Module 命名空间方式导出;
  • export add [provided]:表示 add 这个导出被“提供”且可被静态识别,[no usage info] / [used exports unknown] 表示当前还没有跨模块的使用信息回传;
  • runtime requirements: ...:精确列出该模块运行期依赖的 __webpack_require__ 帮助函数,webpack 据此做“按需注入运行时片段”。

“provided / not provided / used exports unknown”这类状态词汇对应 webpack 的 ExportsInfo 数据结构(维护于 lib/ExportsInfo.js)与导出使用分析(FlagDependencyExportsPluginFlagDependencyUsagePlugin 等),它同时也是 tree shaking 与 stats 输出中 [exports: answer][no exports used] 等信息的来源。这正是 Harmony 模块相比 CommonJS 最大的优势:静态语法让 webpack 能精确知道每个模块导出了什么、被用到了什么,从而为死代码消除(sideEffects 与 tree shaking)铺路。

webpack 运行时(Runtime)逐段解析

在 bundle 里,模块表之后是运行时代码。为了让 bundle 既能同步 require 又能按需加载异步 chunk,运行时提供了成套的 __webpack_require__ 帮助函数。原文 README 用 <details> 折叠块完整保留了这约 200 行运行时,下面分层拆解其职责。

模块缓存与 require 函数

// The module cache
const __webpack_module_cache__ = {};

// The require function
function __webpack_require__(moduleId) {
	// Check if module is in cache
	const cachedModule = __webpack_module_cache__[moduleId];
	if (cachedModule !== undefined) {
		return cachedModule.exports;
	}
	// Create a new module (and put it into the cache)
	const module = __webpack_module_cache__[moduleId] = {
		// no module.id needed
		// no module.loaded needed
		exports: {}
	};
	// Execute the module function
	__webpack_modules__moduleId;
	// Return the exports of the module
	return module.exports;
}

这是最核心的 CommonJS 运行时抽象:首次 require 时创建模块对象并执行包装函数,之后命中 __webpack_module_cache__ 直接返回同一份 exports,从而保证多模块共享单例、避免重复执行副作用。__webpack_require__.m = __webpack_modules__ 则把模块表暴露出来,供 JSONP 回调向表中追加新 chunk 的模块。

定义 harmony 导出 getter:__webpack_require__.d

// define getter/value functions for harmony exports
__webpack_require__.d = (exports, definition) => {
	for(var key in definition) {
		if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
			Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
		}
	}
};

它遍历定义对象,用 Object.defineProperty 把每个导出定义成可枚举的 getter 而非值。这意味着当模块内被导出的变量后续发生变化时,外部读取到的始终是最新绑定,忠实还原了 ES Module “导出是活的绑定(live binding)”的语义;这也是为什么导出的函数/变量都以 () => (/* binding */ x) 闭包形式给出。

标记模块为 ES Module:__webpack_require__.r

// define __esModule on exports
__webpack_require__.r = (exports) => {
	Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
	Object.defineProperty(exports, '__esModule', { value: true });
};

__webpack_require__.r 同时打上 Symbol.toStringTag = 'Module'(使 Object.prototype.toString.call 返回 [object Module])与 __esModule = true(供 Babel/TS 等编译产物的 _interopRequireDefault 判断“是否是 ES Module”)。webpack 自身的互操作运行时 __webpack_require__.n 也以 __esModule 为依据决定 default 的取法,详见 harmony-interop 示例

辅助短函数:__webpack_require__.o

__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop));

hasOwnProperty 的简写,用于 __webpack_require__.d 中避免覆盖已有导出,也用于 chunk 状态查询。

异步 chunk 加载链路(code splitting 的运行时支柱)

示例代码里的 import("./async-loaded") 在运行时并不存在原生 import,它被编译成下面这样:

__webpack_require__.e(/*! import() */ 655).then(() => (__webpack_require__(/*! ./async-loaded */ 3))).then(function(asyncLoaded) {
	console.log(asyncLoaded);
});

即两步走:先 __webpack_require__.e(chunkId) 把 chunk 加载并执行好,再 __webpack_require__(moduleId) 取出模块。整个链路由以下几段运行时组成:

1. ensure chunk 调度器 __webpack_require__.e

__webpack_require__.f = {};
// This file contains only the entry chunk.
// The chunk loading function for additional chunks
__webpack_require__.e = (chunkId) => {
	return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {
		__webpack_require__.fkey;
		return promises;
	}, []));
};

__webpack_require__.f 是“chunk 加载方案注册表”(如 f.j 代表 JavaScript JSONP 方案),e 会聚合所有方案的 promise,因此同一套骨架也能扩展支持 css、importmaps 等其它 chunk 类型。

2. 异步 chunk 文件名 __webpack_require__.u

// This function allow to reference async chunks
__webpack_require__.u = (chunkId) => (chunkId + ".output.js");

因为 output.filename[id].output.js,这里直接拼接出 655.output.js;若配置了 chunkFilename: "[name].bundle.js" 或带 contenthash 的文件名,此函数会相应生成不同的拼接逻辑。

3. script 标签加载 __webpack_require__.l

__webpack_require__.l = (url, done, key, chunkId) => {
	...
	let script, needAttach;
	if(key !== undefined) {
		const scripts = document.getElementsByTagName("script");
		for(var i = 0; i < scripts.length; i++) {
			const s = scripts[i];
			if(s.getAttribute("src") == url) { script = s; break; }
		}
	}
	if(!script) {
		needAttach = true;
		script = document.createElement('script');
		script.charset = 'utf-8';
		if (__webpack_require__.nc) {
			script.setAttribute("nonce", __webpack_require__.nc);
		}
		script.src = url;
	}
	inProgress[url] = [done];
	...
	const timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000);
	script.onerror = onScriptComplete.bind(null, script.onerror);
	script.onload = onScriptComplete.bind(null, script.onload);
	needAttach && document.head.appendChild(script);
};

它负责在浏览器环境用 <script> 标签拉取 chunk 文件,管理 inProgress 去重、timeout 超时、nonce(CSP 支持)以及 onload/onerror 回调。

4. JSONP chunk 加载实现 __webpack_require__.f.j

const installedChunks = {
	792: 0
};
__webpack_require__.f.j = (chunkId, promises) => {
	// JSONP chunk loading for javascript
	let installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;
	if(installedChunkData !== 0) { // 0 means "already installed".
		// a Promise means "currently loading".
		if(installedChunkData) {
			promises.push(installedChunkData[2]);
		} else {
			if(true) { // all chunks have JS
				// setup Promise in chunk cache
				const promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject]));
				promises.push(installedChunkData[2] = promise);
				// create error before stack unwound to get useful stacktrace later
				const error = new Error();
				...
				__webpack_require__.l(__webpack_require__.p + __webpack_require__.u(chunkId), loadingEnded, "chunk-" + chunkId, chunkId);
			}
		}
	}
};

installedChunks 是 chunk 状态表:0 表示已加载完成、[resolve, reject, Promise] 表示加载中、undefined 表示尚未加载。并发触发同一 chunk 的多次 import() 时会复用同一个 Promise。加载失败时则构造带 errorTyperequestevent 细节的 ChunkLoadError 供上层捕获。

5. publicPath __webpack_require__.p

__webpack_require__.p = "dist/";

因为输出目录是 dist,异步脚本的完整 URL 由 __webpack_require__.p + __webpack_require__.u(chunkId) 拼出,即 dist/655.output.js

6. JSONP 回调与 self["webpackChunk"] 全局数组

const webpackJsonpCallback = (parentChunkLoadingFunction, data) => {
	let [chunkIds, moreModules, runtime] = data;
	// add "moreModules" to the modules object,
	// then flag all "chunkIds" as loaded and fire callback
	var moduleId, chunkId, i = 0;
	if(chunkIds.some((id) => (installedChunks[id] !== 0))) {
		for(moduleId in moreModules) {
			if(__webpack_require__.o(moreModules, moduleId)) {
				__webpack_require__.m[moduleId] = moreModules[moduleId];
			}
		}
		if(runtime) var result = runtime(__webpack_require__);
	}
	if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);
	for(;i < chunkIds.length; i++) {
		chunkId = chunkIds[i];
		if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {
			installedChunks[chunkId][0]();
		}
		installedChunks[chunkId] = 0;
	}
};

const chunkLoadingGlobal = self["webpackChunk"] = self["webpackChunk"] || [];
chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));
chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));

异步 chunk 文件内容其实只是一段对全局数组 self["webpackChunk"]push 调用。回调把新 chunk 的 moreModules 灌进 __webpack_require__.m 模块表(此时 async-loaded.js 的模块函数才被登记),再把对应 installedChunks 标记为已加载并 resolve 等待中的 promise,随后入口代码里的 .then(() => __webpack_require__(3)) 即可取回模块。self 而非 window 也意味着这套运行时同样适用于 Web Worker 等非窗口环境。

为什么 module id 3 是 async-loaded.js

回看产物注释 __webpack_require__(/*! ./async-loaded */ 3),异步模块的 module id 在编译期就已分配(id 3),只是它的模块函数直到 chunk 加载完成、JSONP 回调把 moreModules 写入模块表后才可用。这正是“先加载代码、再执行 require”的运行时协作模型。

入口执行代码的最终形态

模块表与运行时之后,是入口模块的引导代码,它被包在独立 IIFE 中以保证与 chunk 中其它模块隔离:

let __webpack_exports__ = {};
// This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk.
(() => {
/*!********************!*\
  !*** ./example.js ***!
  \********************/
/*! namespace exports */
/*! exports [not provided] [no usage info] */
/*! runtime requirements: __webpack_require__, __webpack_require__.r, __webpack_exports__, __webpack_require__.e, __webpack_require__.* */
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _increment__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./increment */ 1);

var a = 1;
(0,_increment__WEBPACK_IMPORTED_MODULE_0__.increment)(a); // 2

// async loading
__webpack_require__.e(/*! import() */ 655).then(() => (__webpack_require__(/*! ./async-loaded */ 3))).then(function(asyncLoaded) {
	console.log(asyncLoaded);
});

})();

可以清楚看到原文源码与产物的逐行对应关系:

源码 编译产物
import { increment as inc } from './increment' var _increment__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1)
inc(a) (0,_increment__WEBPACK_IMPORTED_MODULE_0__.increment)(a)
import("./async-loaded").then(...) __webpack_require__.e(655).then(() => __webpack_require__(3)).then(...)

构建信息解读:Unoptimized 与 Production 的差异

README 的 Info 部分给出了同一份源码在两种模式下的构建统计,逐条解读如下。

Unoptimized(未压缩构建)

asset output.js 11.3 KiB [emitted] (name: main)
asset 655.output.js 761 bytes [emitted]
chunk (runtime: main) 655.output.js 24 bytes [rendered]
  > ./async-loaded ./example.js 6:0-24
  ./async-loaded.js 24 bytes [built] [code generated]
    [exports: answer]
    [used exports unknown]
    import() ./async-loaded ./example.js 6:0-24
chunk (runtime: main) output.js (main) 400 bytes (javascript) 5.34 KiB (runtime) [entry] [rendered]
  > ./example.js main
  runtime modules 5.34 KiB 8 modules
  dependent modules 225 bytes [dependent] 2 modules
  ./example.js 175 bytes [built] [code generated]
    [no exports]
    [used exports unknown]
    entry ./example.js main
  • 两个 asset:主 chunk output.js(11.3 KiB)与异步 chunk 655.output.js(761 bytes)。655 是编译期分配给该异步 chunk 的数值 id;
  • > ./async-loaded ./example.js 6:0-24:指明异步 chunk 的来源是 example.js 第 6 行第 0–24 列(即 import("./async-loaded") 所在位置);
  • 异步模块 [exports: answer][used exports unknown]:非生产模式下没有做深入的导出使用分析,因此显示 unknown;
  • 主 chunk 内 400 bytes javascript + 5.34 KiB runtime(8 个 runtime 模块):运行时体积远大于业务代码,这正是小应用在生产中应启用压缩与精简运行时的原因;
  • dependent modules 225 bytes 2 modules:即 increment.jsmath.js 被归入入口 chunk 的依赖模块。

Production(压缩构建)

asset output.js 2.01 KiB [emitted] [minimized] (name: main)
asset 655.output.js 121 bytes [emitted] [minimized]
...
  ./example.js + 2 modules 400 bytes [built] [code generated]
    [no exports]
    [no exports used]
  • 开启 production 后 Terser 等压缩器介入,主 chunk 从 11.3 KiB 降到 2.01 KiB,异步 chunk 从 761 bytes 降到 121 bytesanswer 常量与最小化模块机制共同作用);
  • 导出使用状态从 [used exports unknown] 变为 [no exports used]——生产模式完成了全量使用分析,为后续按 sideEffects/tree shaking 裁剪预留了精确依据;
  • 统计中 ./example.js + 2 modules 表明入口及其同步依赖被合并统计,这正是基于 Harmony 静态信息才可能做到的深度优化前提。

源码级印证:这些编译行为在仓库哪里实现

如果想进一步验证上述产物背后的机制,可以在仓库源码中找到对应的实现线索:

  • Harmony 依赖族import/export 的静态依赖解析分散在 lib/dependencies 下以 Harmony 命名的约 12 个依赖类中,例如 HarmonyImportSpecifierDependency.js(命名导入引用绑定)、HarmonyExportSpecifierDependency.jsHarmonyImportSideEffectDependency.js(副作用导入)等;模块包装函数内 /* harmony import *//* harmony export */ 注释即源于此类依赖的代码生成逻辑;
  • 导出信息与 tree shaking 基础lib/ExportsInfo.js 承载每个模块的导出/使用状态([provided][no usage info][used exports unknown] 等标记的直接来源);
  • 运行时帮助函数__webpack_require__.e/.d/.o/.r/.u/.l/.p/.f 等符号统一注册于 lib/RuntimeGlobals.js,具体实现分散在 lib/runtime 目录(约 38 个运行时模块),产物中的 "runtime modules 5.34 KiB 8 modules" 对应的正是这些运行时片段的按需集合;
  • 产物生成入口:模块表、包装函数与各依赖模板的拼接发生在代码生成阶段,相关公共逻辑可见 lib/RuntimeModule.jslib/DependencyTemplate 体系。

动手复现与关联示例

如果你想在本机复现这份产物,可以参考 examples/README.md 记录的示例构建流程:在仓库根目录依次执行 yarnyarn setup,然后针对单个示例运行构建命令;仓库同时也提供 examples/buildAll.js 这样的批量构建脚本(它会遍历 examples/examples.js 收集到的所有含 template.md 的示例目录逐一构建)。examples/harmony 目录内的 README 由 template.md 驱动生成,examples/template-common.js 负责把真实构建 stdout 与 dist/output.js 回填进模板;test/Examples.test.js 则在 CI 中驱动这些示例,保证展示的产物与真实编译结果一致。注意:示例展示的运行时代码是浏览器环境下的 JSONP 加载实现,Node 环境或开启了 HMR、output.chunkLoading 等不同配置时,运行时会随之更换。

围绕 Harmony 模块,仓库还提供了多个互补示例,适合串联阅读:

小结

examples/harmony 是一个“小切口、大纵深”的教科书式示例:仅 4 个文件,却完整覆盖了 ES Module 同步导入、命名导出、模块再导出、动态 import() 代码分割四大主题。透过这份产物你能直观确认三件事:其一,webpack 用“模块包装函数 + 模块缓存 + __webpack_require__”复刻了模块系统,并用 __webpack_require__.r/.d 还原 ESM 的命名空间与只读绑定语义;其二,import() 是编译期静态解析的代码分割点,会在运行时被替换成 __webpack_require__.e(chunkId) 驱动 JSONP 加载再 __webpack_require__(moduleId) 取模块的完整流程;其三,每个 Harmony 模块的导出/使用信息都被精确记录([provided][used exports unknown] 等注释),这正是生产模式下压缩体积与 tree shaking 得以奏效的数据基础。理解了这个最小闭环,再去看 webpack 的 tree shaking、scope hoisting、module federation 等高级特性,都会顺畅得多。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.81 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
920
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.79 K
1.02 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
390