首页
/ Infisical 外部 E2E 测试套件实战:用 Playwright 与自建 Mock SAML IdP 守护生产部署

Infisical 外部 E2E 测试套件实战:用 Playwright 与自建 Mock SAML IdP 守护生产部署

2026-09-09 15:07:22作者:凤尚柏Louis

导读

在 Infisical 仓库中,e2e/ 目录承载着一套特殊的端到端测试套件:它不是对后端进程的内部单元/集成测试,而是以黑盒方式面向已部署的 gamma 环境运行 Playwright 测试,在 CI 中充当"部署到生产前"的最后一道门禁。本文以 e2e/CLAUDE.md 为核心骨架,结合套件源码与后端 SCIM/SAML 实现,完整讲解其定位、架构(自建 Mock SAML IdP、双 Token CI 表面)、承重身份耦合模型、串行执行设计、新增测试的规范流程,以及最容易"静默破坏"的外部依赖同步清单。读完你将掌握:如何在 Infisical 或同类产品中,用一套零 SaaS 依赖的 E2E 套件验证 SCIM 置备与 SAML 登录在真实部署上的行为,并理解其背后的测试设计取舍。


一、这个套件是什么:部署门禁而非单元测试

1.1 定位:gamma 与生产之间的门禁

e2e/ 目录下的套件被明确定义为 External Playwright suite:它面向一个已部署的 Infisical 环境(代号 gamma)运行,而非本地进程。在 CI 中,它位于 gamma-deployment 与任何生产部署任务之间,对应 infrastructure 仓库中 .github/workflows/infisical-deployment.yml 里的 gamma-playwright-e2e 作业。一旦该作业失败(红灯),通过 needs: 依赖关系会阻塞全部 11 个生产/专享部署作业——这是它的"门禁"意义所在。

不是 backend/e2e-test/ 那套测试。后者的关键区别在于:

维度 backend/e2e-test/ e2e/(本套件)
运行方式 进程内 Vitest,自带引导启动的后端服务器 外部 Playwright,面向已部署的 gamma 环境
测试对象 后端隔离环境(in-process) 部署后的真实产品(黑盒)
关注点 业务逻辑正确性 配置漂移、部署回归、依赖真实 IdP 的端到端认证流

1.2 范围纪律:smoke 级验证

套件遵循严格的范围纪律:只做"表面是否仍能在真实基础设施上端到端工作"的 smoke 级验证。如果某个测试本质上可以表述为"给定函数输入,断言函数输出",那它就应该属于单元测试或集成测试,而不是这里——因为 CI 中每个测试的代价以"分钟"而非"秒"计,窄覆盖会非常昂贵。

一个具体而可操作的判断规则是:这里的测试即使所有集成测试都通过,也仍然有用。它捕捉的是集成测试抓不到的问题——配置漂移、部署回归、依赖真实 IdP 的端到端认证流。这也是后续所有设计(Mock IdP、串行执行、身份耦合)的出发点。


二、架构全景:四个关键支柱

2.1 Playwright 配置:单 Worker、纯 Chromium

套件基于 Playwright(TypeScript),从 e2e/playwright.config.ts 可以看到完整约束:

  • 仅 Chromium 项目,使用 devices["Desktop Chrome"]
  • 单 Worker + fullyParallel: false——这是承重约束,详见"串行执行是有意的"一节;
  • CI 与非 CI 差异化:CI 下 retries: 2forbidOnly: true,reporter 组合为 github + html + list;本地则 html 报告仅在失败时打开;
  • 超时配置:单测试 60s,expect 断言 10s,action 15s,导航 30s;
  • 失败取证trace: "retain-on-failure"screenshot: "only-on-failure"video: "retain-on-failure",保证红灯时可回放完整现场。

2.2 双 Token CI 表面:env 只装真秘密

整个 CI 的秘密面被刻意压缩到最小:只有两个真正的秘密从环境变量读取——E2E_SCIM_TOKEN(SCIM 置备接口的 Bearer Token)和 E2E_IDP_ADMIN_TOKEN(Mock IdP 的管理 Token)。它们通过 e2e/helpers/env.ts 中的 required() 做**失败即报错(fail-fast)**加载:

export const env = {
  scimToken: required("E2E_SCIM_TOKEN"),
  idpAdminToken: required("E2E_IDP_ADMIN_TOKEN")
};

其余部署级标识符(gamma URL、组织 slug、IdP URL、SAML 配置行 id)全部硬编码在 e2e/helpers/constants.ts 中,例如:

export const GAMMA_BASE_URL = "https://gamma.infisical.com";
export const E2E_ORG_SLUG = "e2e-scim-test";
export const IDP_BASE_URL = "https://preview-orchestrator.infisical.workers.dev";
export const SAML_CONFIG_ID = "03b67793-60a4-4d83-84cf-79c9b334d7c3";

这是一个深思熟虑的取舍:重新播种 gamma 的 e2e 组织会轮换 saml_configs.id,此时只需要改代码里的常量(种子脚本会在 [seed] E2E_SAML_CONFIG_ID = <uuid> 行打印新值),而无需操作 GH Actions 秘密。代价是改代码而非改配置,但换来的是 CI 秘密面最小化。注意 constants.tsSAML_CONFIG_ID 过期会导致 gamma 对 ACS POST 返回 404、IdP-initiated 测试失败在重定向断言上。

2.3 Twingate 网络门禁

gamma 位于 Twingate 之后,CI 工作流在测试运行前安装 Twingate 连接器;本地运行则同样需要接入 Twingate。Playwright 的 Chromium 直接继承宿主网络连接器的路由,因此测试代码本身不需要任何网络配置。

2.4 自建 Mock IdP:零 SaaS 依赖的 SAML 端点

SAML SSO 指向 preview-orchestrator.infisical.workers.dev/saml-idp/*——这是部署在既有 preview-environments Worker 上的 Hono 路由,使用 samlifynodejs_compat 下完成签名。没有 SaaS 账号,没有厂商 DOM 可漂移

完整流程(见 e2e/helpers/idp-client.tsprimeSamlIdentity):

  1. 测试先调用 POST /saml-idp/identity,携带本次运行的 NameID(以及 IdP-initiated 场景下经 gamma SP origin 白名单校验过的 ACS URL);
  2. Worker 返回 session id,测试通过 ctx.addCookies 把会话 cookie 写在 Worker 域名上(path=/saml-idpsameSite=None + secure,保证跨源重定向时 cookie 可随行);
  3. 浏览器导航到 gamma 的 SAML 启动 URL,gamma 302 到 IdP,cookie 随行,IdP 为该身份铸造签名断言。

证书分离是安全关键:公钥证书提交在仓库 e2e/fixtures/idp-cert.pem,私钥只存在于 Cloudflare Secrets(SAML_IDP_PRIVATE_KEY),永不入库。证书的生成、有效期与轮换细节见 e2e/fixtures/README.md:用 openssl req 生成、10 年有效期是刻意的(仅测试用),轮换需同时更新 Worker 私钥、替换证书文件并重跑种子脚本(幂等)。

2.5 两种 SAML 入口,一个 spec 文件

e2e/tests/scim-saml-auth.spec.ts 在同一个 test.describe 下覆盖两个变体:

  • SP-initiated:浏览器先导航到 gamma 的 /api/v1/sso/redirect/saml2/organizations/:orgSlug,gamma 带着 AuthnRequest 302 浏览器到 Worker 的 /saml-idp/sso
  • IdP-initiated:浏览器直接访问 Worker 的 /saml-idp/initiate,该端点铸造一个**未经请求的(unsolicited)**签名 SAMLResponse(按 SAML 2.0 §3.4.1.5 不含 InResponseTo),并自动 POST 到 gamma 的 ACS /api/v1/sso/saml2/:samlConfigId。ACS URL 通过 POST /identity 传入(经 gamma SP origin 白名单校验),可经 gammaSamlAcsUrl() 获得。

IdP-initiated 分支之所以能工作,依赖 @node-saml/node-saml 5.x 中 validateInResponseTo 默认值为 "never"——Worker 的 unsolicited 模板完全省略 InResponseTo,使测试在该默认值将来被收紧时依然有效。


三、承重身份耦合:SCIM userName == SAML NameID == UserAlias.externalId

这是整个套件中最容易"静默失败且难以排查"的细节:

SCIM userName  ==  SAML NameID(IdP 签发)  ==  UserAlias.externalId

链条成立的底层依据(均有后端源码佐证):

  • SCIM 置备创建 UserAlias.externalId = req.body.userName(后端 scim-router.tsscim-service.ts 的 SCIM 用户创建路径);
  • 组织认证方式为 SAML,因此别名类型是 SAML(scim-service.tsaliasType: SAML 的分支);
  • SAML 登录时按 userAliasDAL.findOne({ externalId: profile.nameID, orgId, aliasType: SAML }) 查找(saml-config-service.ts)。

自建 Mock IdP 让测试端到端地拥有这个值:每次运行生成唯一的 EXTERNAL_ID(形如 e2e-${runId}@infisical-e2e.test),并把同一个字符串同时作为 SCIM 的 userName、IdP 的 email(samlify 用它作为 SAML NameID),从而隐式地成为 UserAlias.externalId。没有 SaaS 侧的配置可漂移——只要 e2e/tests/scim-saml-auth.spec.tse2e/helpers/idp-client.ts 对这个值保持一致,链条就成立。

当前测试的断言终点停在 /signup/sso?token=… 而非 /login/select-organization:因为 gamma 的 SCIM 服务把 userAlias.isEmailVerified 硬编码为 falsescim-service.ts 中 SCIM 创建用户路径),而 auth-login-service.tsSIGNUP_REQUIRED 分支会把任何 isEmailVerified = false 的用户路由到 signup。signup token JWT 内携带已验证的身份字段(authTokenTypeauthMethodemailfirstName/lastNameuserIdaliasIdorganizationId),是"完整 SAML 流程对目标身份端到端生效"的最强可验证信号——gamma 信任了 IdP 签名、校验了 audience(SP-initiated 分支还校验了 InResponseTo)、提取了断言属性、并命中 SCIM 创建的同一条 user_alias。若未来修补 SCIM 服务让别名在置备时即标记为已验证,重定向会切回 /login/select-organization,测试断言需同步更新。


四、串行执行是有意的

历史上单 Worker 是为了"单一静态 IdP 身份",如今这个理由已消失——Mock IdP 可以为测试索要的任何 NameID 铸造断言,每次运行唯一 externalId 已经可行。

真正绑定单 Worker 的是共享的 gamma 组织:只有一个 saml_configs 行、一组 email_domains 行、一个 orgAuthMethod。并发测试同时写入同一组织的 user_aliases/memberships 行,可能产生微妙的交错(例如同一个邮箱同时从两个流程落到兜底的 userDAL.findOne({ username }) 上)。要解除并行限制,要么为每个测试建独立 gamma 组织(更重的种子脚本),要么对不触碰共享组织状态的测试接受该风险。

若确需启用并行 Worker,还需确认 IdP /saml-idp/identity 流程的 cookie 作用域仍然成立:Worker 将 cookie 设为 path=/saml-idp,多个并发测试可在 Worker origin 上各自设置自己的 session cookie 值而不冲突(Playwright context 本身已按测试隔离)。


五、文件布局:每份文件该何时动

原文档给出了完整的文件布局表,整理如下(路径均已转换为仓库根目录相对路径):

路径 用途 何时需要改动
e2e/playwright.config.ts Runner 配置——baseURL、retries、reporter 新增项目(如 Firefox)、调整重试策略
e2e/helpers/env.ts 两个 Bearer Token 秘密的 fail-fast 加载器 新增秘密(同步更新 .env.example 与 CI 工作流);非秘密配置放 constants.ts
e2e/helpers/constants.ts 硬编码部署级标识符(gamma URL、org slug、IdP URL、SAML config id) gamma e2e 组织被重新引导、saml_configs.id 轮换时更新 SAML_CONFIG_ID(种子脚本在 [seed] E2E_SAML_CONFIG_ID = <uuid> 行打印新值)
e2e/helpers/scim.ts SCIM CRUD 包装器,跨测试复用 测试需要新的 SCIM 操作(如 Groups)时
e2e/helpers/idp-client.ts 与 Mock IdP 通信——暂存 NameID(+ IdP-initiated 的 ACS URL)、设置 Worker 域 session cookie、启动 SP/IdP-initiated 流程 新增 SAML 变体流程,或 Worker IdP 的 API/cookie 方案变更
e2e/tests/*.spec.ts 每个流程一个文件 新增流程(见下文)
e2e/fixtures/idp-cert.pem Mock IdP 的已提交公钥证书;gamma 的 SAML 配置行持有同一张证书(KMS 加密) 轮换 IdP 密钥对时(见 e2e/fixtures/README.md
e2e/tsconfig.json TS 配置——刻意不用 baseUrl/paths,仅相对导入 除非有真实理由,否则避免改动

5.1 SCIM 帮助器的核心操作

e2e/helpers/scim.ts 封装了测试所需的最小 SCIM CRUD 面,全部走 /api/v1/scim 前缀,携带 Authorization: Bearer ${env.scimToken}application/scim+json 头:

  • createScimUser:POST /api/v1/scim/UsersuserName 即外部 id,emails 为主邮箱,active: true
  • findScimUserByExternalId:GET /api/v1/scim/UsersuserName eq "..." 过滤;
  • deleteScimUser:DELETE /api/v1/scim/Users/:id(404 容忍);
  • ensureScimUserAbsent:先查后删的防御性清理;
  • setScimUserActive:PATCH { op: "replace", path: "active", value: ... }(按 RFC 7644 §3.5.2),翻转 memberships.isActive

5.2 Mock IdP 客户端的两条流程

e2e/helpers/idp-client.ts 暴露:

  • primeSamlIdentity(page, identity):POST /saml-idp/identity(Bearer E2E_IDP_ADMIN_TOKEN),随后把返回的 session cookie 写到测试浏览器 context 的 Worker 域上;
  • startSamlLogin(page):导航到 SP-initiated 的 gamma 启动 URL;
  • startIdpInitiatedLogin(page):导航到 Worker /saml-idp/initiate(前置条件:primeSamlIdentity 时传 acsUrl: gammaSamlAcsUrl());
  • gammaSamlAcsUrl():按 ${appCfg.SITE_URL}/api/v1/sso/saml2/${configId} 拼出 gamma 的 ACS 地址(对应后端 saml-router 中的 callbackUrl)。

IdpIdentity 类型还支持 assertionOverrides——供拒绝类测试故意制造损坏断言(错误 audience、过期的 NotOnOrAfter、不匹配的 InResponseTo)。


六、新增测试的方法论

原文档给出了 8 条明确规范,这是本套件最重要的贡献性约束:

  1. 一个文件 = 一个"流程",而非一个测试。流程是待验证的独立端到端路径(如"SCIM 置备用户通过 SAML 登录"、"SAML 响应被拒绝"、"SCIM 停用撤销 SAML 登录")。同一流程中仅入口形态或输入不同的变体(SP-initiated vs IdP-initiated;拒绝套件中的每个严格性关卡)归入同一文件的同一个 test.describe,作为多个 test()
  2. 文件以流程命名scim-saml-auth.spec.tssaml-rejection.spec.tsscim-deactivation.spec.ts),变体命名放在文件内的测试标题中。
  3. 只从 helpers/constantshelpers/envhelpers/scimhelpers/idp-client 导入;只有全新流程需要共享 setup 时才新增 helper 模块。
  4. 变体状态放 beforeEach/afterEach,不放 beforeAll/afterAll。每个变体测试拥有自己全新的 SCIM 用户(全新 externalId),一个变体中途崩溃不会污染下一个(参见 saml-rejection.spec.ts 的模式)。只有文件级真正共享且幂等的状态才用 beforeAll/afterAll
  5. 始终清理beforeEach 防御性删除测试要创建的任何状态,afterEach 删除测试产生的状态。测试经常中途崩溃,否则 e2e 组织会积累行。
  6. 每个测试一个断言块通常就够。多个测试断言同一结果形态时,在文件内提取共享的 expect…() 帮助器(如 scim-saml-auth.spec.ts 中的 expectSignupSsoRedirectFor(page, email)),而不是在测试间复制约 10 行 expect。不要把 smoke 测试扩成单元测试式断言 sprawl——细粒度细节应推向集成测试。
  7. 不要在 spec 文件之间共享帮助器。帮助器只存在于 helpers/* 或作为 spec 文件顶部的文件内常量/函数;跨 spec 导入会制造 CI 调试悬崖。
  8. 先本地跑通再上 CI:用 .env 填充环境后执行 npm test;CI 通过 GH Actions 秘密复刻。

6.1 三条现有流程的验证要点

SCIM 置备 + SAML 登录e2e/tests/scim-saml-auth.spec.ts):SP-initiated 与 IdP-initiated 两个变体共享 expectSignupSsoRedirectFor——断言 URL 匹配 /signup/sso?token=、token 存在且可解出 JWT payload(authTokenType === "signupToken"authMethod === "keycloak-saml"email 等于 IdP 签发的 NameID、userId/aliasId/organizationId 均为 UUID)。JWT 不解签——签名是 gamma 的,且刚刚通过 TLS 收到,信任即可。

SAML 响应拒绝e2e/tests/saml-rejection.spec.ts):每个子测试让 Mock IdP 铸造一个刻意损坏的断言,并断言 gamma 的 ACS POST 返回 400——audience 不匹配、NotOnOrAfter 过期(10 分钟前,远超时钟偏移容忍)。gamma 的 saml-router 会把 passport-saml 校验错误翻译成 BadRequestError → Fastify 返回 400 JSON。若某次回归静默禁用了签名/audience/InResponseTo/Conditions 校验,这些 400 会翻转为 302 跳转,测试随即失败。

SCIM 停用撤销 SAML 登录e2e/tests/scim-deactivation.spec.ts):先创建用户并断言 active === true,PATCH 置 active: false 并断言持久化,再走 SAML 登录并断言 ACS POST 返回 >= 400 && < 500——用 4xx 区间而非精确值,因为停用检查落在哪一层(saml-router 的 400 包装,或登录服务层的 401/403)可能演进,测试要防的只是"302 跳转 = 被接受"这一方向。


七、你可能意外破坏的东西:外部依赖同步清单

这些外部依赖必须保持同步——改后端或 Worker 会让测试静默失败。任何涉及以下区域的改动后都值得 grep 一遍:

  • SCIM 端点 URL(后端 scim-router.ts,挂载于 /api/v1/scim)。helpers/scim.ts 硬编码 /api/v1/scim/Users/api/v1/scim/Users/:id,路由前缀移动需同步。
  • SAML 启动/ACS URL(后端 saml-router.ts)。helpers/idp-client.ts 硬编码 /api/v1/sso/redirect/saml2/organizations/:orgSlug(SP-initiated)与 /api/v1/sso/saml2/:samlConfigId(IdP-initiated ACS,由 constants.tsSAML_CONFIG_ID 拼出)。任一路径移动,两处消费点都要跟随。
  • 登录后重定向saml-config-service.tsauth-login-service.tsSIGNUP_REQUIRED 分支)。scim-saml-auth.spec.ts 断言 /signup/sso?token=…;若 SCIM 被修补为置备时标记别名已验证,重定向翻转为 /login/select-organization,断言需跟随。
  • NameID → externalId 映射saml-config-service.ts)。当前取 profile.nameID;若匹配属性变更,上文"身份耦合"一节即过时。
  • scimEnabled / orgAuthMethod 语义scim-service.ts)。若新增门禁(如附加 flag),种子脚本 backend/scripts/seed-gamma-fixtures.ts 需同步设置。
  • 已验证邮箱域名检查email-domain-fns.ts)。SCIM POST 与 SAML 登录都要求邮箱域名在组织的 email_domains 允许名单中且 status='verified';种子脚本为 infisical-e2e.test 写入一行。测试若改用其他域名,需加行。
  • Mock IdP 证书 ↔ gamma SAML 配置证书必须匹配。种子脚本读取 e2e/fixtures/idp-cert.pem 并 KMS 加密进 saml_configs 行;Worker 用 SAML_IDP_PRIVATE_KEY(CF Secret)签名。轮换其一必须轮换其二——见 e2e/fixtures/README.md
  • passport-saml 严格性saml-router.ts)。在 authProvider = keycloak-saml(种子脚本所写)下无 overrides 生效——passport-saml 要求 Response 与 Assertion 均签名、存在 email/firstName/lastName 属性、audience 匹配 appCfg.SITE_URLvalidateInResponseTo 默认 "never"@node-saml/node-saml 5.x)是 IdP-initiated 路径能工作的原因;改为 "ifPresent"/"always" 会先破坏 IdP-initiated。改变种子的 authProvider 值会改变严格性画像。

八、种子脚本:一次性引导 e2e 组织

e2e/backend/scripts/seed-gamma-fixtures.ts(从 backend/ 目录运行)是幂等引导脚本,创建:

  1. e2e 组织e2e-scim-testscimEnabled: true);
  2. 常驻 admin 成员e2e-admin@infisical-e2e.test)——必须存在,否则 deleteOrgMembershipsFn 的最后管理员守卫会让每个 SCIM DELETE 返回 400;
  3. SCIM token 行,并用 AUTH_SECRET 签发 E2E_SCIM_TOKEN(每跑一次重新打印,便于重新捕获);
  4. SAML 配置行authProvider = keycloak-samlisActive: true,entryPoint/issuer/证书均用组织级 KMS 数据密钥加密——与运行时 SAML 服务的解密路径完全一致,因此 gamma 的 getSaml() 解密后看到的值与管理员 API 写入的完全相同;
  5. 已验证邮箱域名行infisical-e2e.teststatus='verified'),绕过 DNS-TXT 验证流程直接插库。

安全设计是硬约束:脚本拒绝任何看起来像生产的环境(host/库名正则 PROD_PATTERN + INFISICAL_ENV=prod 检查 + 必须交互式重新输入库名确认)。不要用 yes 管道绕过确认——那会破坏安全目的。

运行方式(示例,需替换为 gamma 的实际连接串与密钥):

DB_CONNECTION_URI=<gamma uri> \
ENCRYPTION_KEY=<gamma encryption key> \
AUTH_SECRET=<gamma auth secret> \
E2E_ORG_NAME="e2e-scim-test" E2E_ORG_SLUG="e2e-scim-test" \
npx tsx scripts/seed-gamma-fixtures.ts

脚本输出的 E2E_SCIM_TOKENE2E_SAML_CONFIG_ID 分别进入 CI 秘密与 constants.ts


九、常见陷阱与排查指南

  • npm install 之前出现 @playwright/test 相关诊断报错——属预期,执行 cd e2e && npm install 即可解决。
  • 种子脚本的引导是一次通过:直接写库不触发 updateSamlCfgscimEnabled=false 副作用,单次运行即得到可用状态(旧的 SSOJet 时代两次运行的要求已消失);重跑依然安全(幂等)。
  • /saml-idp/* 必须有 CF Access 绕过:否则对 Mock IdP 的每个请求都会 302 到 CF Access 登录页。绕过是安全的,因为 IdP 路由自带认证(/identityAuthorization: Bearer SAML_IDP_ADMIN_TOKEN/sso/initiate 用 cookie + KV 查找,/metadata.xml 有意公开)。
  • Worker 改动通过 wrangler deploy 发布,而非 gamma 部署:编辑 Worker 代码(/saml-idp/* 路由、IdP 模板)后,必须先从 preview-environments 仓库部署再跑测试,否则命中的是旧版本。tsc 通过不代表 Worker 已更新。
  • SCIM POST + SAML signup 每次运行泄漏一行 user:SAML signup 分支即便 SCIM 已创建用户也会新建 users 行;SCIM DELETE /Users/:id 只删 membership 不删孤儿用户。可接受但会累积,噪音变大时需回头处理。
  • 不要在 e2e/ 添加 .npmrc 执行 7 天最小发布年龄规则——e2e/ 是测试工具而非运行时产物,backend//frontend/ 中支撑该规则的供应链担忧在这里不适用。
  • CI 使用 npm ci 依赖已提交的 package-lock.json 保证确定性:变更依赖须重新生成 lockfile(npm install)并同次提交,否则 npm ci 会拖垮生产门禁。
  • 不要随意扩大种子脚本的创建范围,除非想清楚了安全性——它已拒绝生产环境(host/库名正则 + INFISICAL_ENV=prod + 交互确认)。加入更强操作意味着重新评估守卫面。

十、上下文地图:相关代码与文档位置


小结

Infisical 的 e2e/ 套件是一个少见的"以部署为靶场"的测试设计样本:它用自建 Mock IdP 消灭了外部依赖的漂移面,用双 Token CI 秘密面最小化运维负担,用单 Worker 串行换取共享组织状态下的确定性,并用一份严格的新增测试规范(一文件一流程、变体状态进 beforeEach、始终清理)把 smoke 测试约束在合理的成本边界内。理解它的架构与边界,不仅能帮你安全地扩展现有流程,也能为同类"生产门禁型"E2E 套件提供可直接借鉴的设计取舍。

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

项目优选

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