首页
/ OpenMontage 字幕工程实战:基于 Remotion Caption JSON 的字幕生成、显示与导入全流程

OpenMontage 字幕工程实战:基于 Remotion Caption JSON 的字幕生成、显示与导入全流程

2026-09-09 21:09:49作者:廉皓灿Ida

字幕与旁白同步是视频生产中最高频也最容易出错的环节。OpenMontage 在 .claude/skills/remotion-best-practices/rules/subtitles.md 中为 Remotion 渲染链路制定了统一规范:所有字幕必须以 JSON 处理,统一采用 @remotion/captionsCaption 类型,并围绕"生成(转写)→ 显示(分页渲染)→ 导入(SRT 解析)"三个阶段给出可运行的 TypeScript 示例。读完本文,你将掌握 Caption 数据结构的字段语义、Whisper.cpp 转录到 JSON 的完整流程、TikTok 风格分页与词级高亮的实现原理,以及如何将已有 .srt 文件无缝并入 Remotion 渲染管线;同时结合 OpenMontage 仓库中的 CaptionOverlay.tsxremotion_caption_burn.py 源码,理解这套规则在生产链路中的真实落地方式。

一、核心规范:所有字幕必须以 JSON 与 Caption 类型统一

规则文件开门见山,给出两条不可妥协的约束:

  1. 所有字幕必须用 JSON 处理,不允许在组件内直接解析文本格式或硬编码字幕串;
  2. 必须使用 @remotion/captions 包导出的 Caption 类型作为字幕数据的唯一结构:
import type { Caption } from "@remotion/captions";

其完整定义如下:

type Caption = {
  text: string;
  startMs: number;
  endMs: number;
  timestampMs: number | null;
  confidence: number | null;
};

各字段含义:

字段 类型 说明
text string 字幕文本内容。规则特别提醒:文本对空白敏感,通常需要在每个词前保留空格(见"显示"阶段的 whiteSpace: "pre" 处理)
startMs number 该条字幕的起始时间,单位为毫秒,用于换算 Remotion 帧号
endMs number 该条字幕的结束时间,单位为毫秒
timestampMs number | null 可选的精确时间戳(词级时间戳场景),无值时为 null
confidence number | null 语音识别置信度,由转写引擎(如 Whisper)产生,无值时为 null

这一设计的核心价值在于数据与表现分离:字幕只是纯数据(JSON),如何展示完全由渲染层决定。OpenMontage 的 Remotion 工程 remotion-composer/package.json 已将 @remotion/captions 固定为 ^4.0.484 依赖,与 remotion 本体版本对齐,确保类型与运行时一致。

值得说明的是,OpenMontage 在仓库内部还定义了一个贴近生产使用的变体——CaptionOverlay.tsx 中的 WordCaption 接口:

export interface WordCaption {
  word: string;
  startMs: number;
  endMs: number;
  // Force a page break after this word (e.g. sentence or scene boundaries).
  // Useful for CJK captions where pages should align with clause boundaries.
  pageBreakAfter?: boolean;
}

它把 Caption 的通用结构收敛为词级粒度的渲染输入,并额外提供 pageBreakAfter 标记位,用于在句末或场景边界强制分页——这对中文等无词间空格的 CJK 字幕尤其重要(规则文件本身面向空格分隔语言,CJK 场景由该组件补齐)。从源码结构看,WordCaptionCaption 在"词级渲染"这一具体用途上的适配,两者字段语义(startMs/endMs)完全对齐。

规则文件将该流程拆成三个子主题,并分别指向三个子规则文档:生成(transcribe-captions.md)、显示(display-captions.md)、导入(import-srt-captions.md)。下面逐一展开。

二、生成字幕:用 Whisper.cpp 把音频转写成 Caption JSON

字幕数据从哪里来?规则给出的首选方案是本地 Whisper.cpp 转写,对应 transcribe-captions.md

2.1 安装依赖

@remotion/install-whisper-cpp 包负责下载 Whisper.cpp 可执行文件与模型,并通过 Node API 驱动转写。使用 Remotion 官方脚手架命令安装:

npx remotion add @remotion/install-whisper-cpp

2.2 转写脚本全流程

规则提供了一个可直接运行的 Node.js 脚本骨架,它完成"安装引擎 → 下载模型 → 转写 → 后处理 → 输出 JSON"五步:

import path from "path";
import {
  downloadWhisperModel,
  installWhisperCpp,
  transcribe,
  toCaptions,
} from "@remotion/install-whisper-cpp";
import fs from "fs";

const to = path.join(process.cwd(), "whisper.cpp");

await installWhisperCpp({
  to,
  version: "1.5.5",
});

await downloadWhisperModel({
  model: "medium.en",
  folder: to,
});

// Convert the audio to a 16KHz wav file first if needed:
// import {execSync} from 'child_process';
// execSync('ffmpeg -i /path/to/audio.mp4 -ar 16000 /path/to/audio.wav -y');

const whisperCppOutput = await transcribe({
  model: "medium.en",
  whisperPath: to,
  whisperCppVersion: "1.5.5",
  inputPath: "/path/to/audio123.wav",
  tokenLevelTimestamps: true,
});

// Optional: Apply our recommended postprocessing
const { captions } = toCaptions({
  whisperCppOutput,
});

// Write it to the public/ folder so it can be fetched from Remotion
fs.writeFileSync("captions123.json", JSON.stringify(captions, null, 2));

关键参数说明:

  • installWhisperCpp({ to, version })to 是 Whisper.cpp 的安装目录(示例中为当前工作目录下的 whisper.cpp/),version 指定引擎版本,示例固定为 1.5.5,保证可复现。
  • downloadWhisperModel({ model, folder }):模型名示例为 medium.en(英文专用中量级模型,在精度与速度间平衡较好);模型文件下载到 folderto 目录。如需其他语言或更小模型,可替换为 tiny / base / small / large-v3 等 Whisper 标准模型名。
  • transcribe({ model, whisperPath, whisperCppVersion, inputPath, tokenLevelTimestamps }):核心转写调用。inputPath 必须是音频文件路径;tokenLevelTimestamps: true 开启词级(token 级)时间戳,这是后面做词高亮(karaoke 效果)的数据前提。
  • 输入格式约束:Whisper 对 16kHz 单声道 WAV 兼容性最佳。规则给出注释示例,先用 FFmpeg 统一转码:
ffmpeg -i /path/to/audio.mp4 -ar 16000 /path/to/audio.wav -y
  • toCaptions({ whisperCppOutput }):把 Whisper.cpp 的原始输出后处理为 Caption[](即第一节的 JSON 结构),规则称之为"推荐的后处理",负责把引擎输出规整为符合 Caption 字段语义的数组。
  • 输出位置:写入 public/ 目录(示例文件 captions123.json),这样 Remotion 组件才能通过 staticFile() 在浏览器与渲染进程中取到。

规则最后强调一条工程惯例:每个片段(clip)单独转写、单独生成 JSON 文件,而不是把整条长视频一次转写。这便于按镜头粒度管理字幕、单独重转写失败的片段,也让每份 JSON 与对应视频资源一一对应。

2.3 仓库中的配套实现

OpenMontage 将"转写得到词级时间戳"这一前置环节交由 tools/analysis/transcriber.pytranscriber 工具)完成,其产物是带 words 数组(每项含 word/start/end)的分段结构。真正消费这些词级数据并落到 Remotion 渲染的是 remotion_caption_burn.py 中的 RemotionCaptionBurn 工具:其 _segments_to_word_captions() 方法(L182-L217)把 transcriber 的词级片段转换为 [{word, startMs, endMs}, ...],秒级时间戳乘 1000 转为毫秒;当片段缺少词级时间戳时,则退化为"按词均分片段时长"的兜底策略(_segments_to_word_captionsper_word = dur / max(len(text_words), 1)),并支持 corrections 字典对语音识别常见误词做大小写不敏感的纠错替换——这与规则中 toCaptions 后处理的定位一致,都是"引擎输出 → 规整 Caption 数据"的适配层。

三、显示字幕:TikTok 风格分页与词级高亮

字幕数据就绪后,如何渲染?对应 display-captions.md。这套方案专为短视频竖屏场景设计:按"页"分组词、每页一个 <Sequence>、当前词高亮

3.1 安装依赖

npx remotion add @remotion/captions

3.2 加载字幕 JSON(useDelayRender 门控渲染)

字幕是异步 fetch 的,在数据到达前不能让 Remotion 进入渲染。规则使用 useDelayRender() 挂起渲染,直到 JSON 加载完成:

import { useState, useEffect, useCallback } from "react";
import { AbsoluteFill, staticFile, useDelayRender } from "remotion";
import type { Caption } from "@remotion/captions";

export const MyComponent: React.FC = () => {
  const [captions, setCaptions] = useState<Caption[] | null>(null);
  const { delayRender, continueRender, cancelRender } = useDelayRender();
  const [handle] = useState(() => delayRender());

  const fetchCaptions = useCallback(async () => {
    try {
      // Assuming captions.json is in the public/ folder.
      const response = await fetch(staticFile("captions123.json"));
      const data = await response.json();
      setCaptions(data);
      continueRender(handle);
    } catch (e) {
      cancelRender(e);
    }
  }, [continueRender, cancelRender, handle]);

  useEffect(() => {
    fetchCaptions();
  }, [fetchCaptions]);

  if (!captions) {
    return null;
  }

  return <AbsoluteFill>{/* Render captions here */}</AbsoluteFill>;
};

这里有三点设计值得注意:

  • delayRender() 返回的 handle 必须保存,加载成功后调用 continueRender(handle) 放行渲染,失败时 cancelRender(e) 让渲染报错退出——避免"字幕未加载完就出帧"或"静默黑屏"两类事故;
  • staticFile("captions123.json") 引用 public/ 下的文件,浏览器端与 headless 渲染端路径一致;
  • 数据未就绪时直接返回 null,不渲染任何内容。

3.3 创建分页:createTikTokStyleCaptions

规则要求用 createTikTokStyleCaptions() 把连续的词分组为"页",combineTokensWithinMilliseconds 决定每页容纳多少词:

import { useMemo } from "react";
import { createTikTokStyleCaptions } from "@remotion/captions";
import type { Caption } from "@remotion/captions";

// How often captions should switch (in milliseconds)
// Higher values = more words per page
// Lower values = fewer words (more word-by-word)
const SWITCH_CAPTIONS_EVERY_MS = 1200;

const { pages } = useMemo(() => {
  return createTikTokStyleCaptions({
    captions,
    combineTokensWithinMilliseconds: SWITCH_CAPTIONS_EVERY_MS,
  });
}, [captions]);

参数语义:数值越大,同一页内合并的词越多(接近整句一屏);数值越小,每页词越少(趋向逐词跳动)。示例取 1200ms,即大约每 1.2 秒切换一页。pages 数组由 useMemo 缓存,避免每次渲染重复分组。

3.4 用 Sequence 按页渲染

分页结果中的每一页都是一个带时间窗(startMs 及下一页的起始)的渲染单元,映射为 Remotion 的 <Sequence>,起止帧由毫秒按 fps 换算:

import { Sequence, useVideoConfig, AbsoluteFill } from "remotion";
import type { TikTokPage } from "@remotion/captions";

const CaptionedContent: React.FC = () => {
  const { fps } = useVideoConfig();

  return (
    <AbsoluteFill>
      {pages.map((page, index) => {
        const nextPage = pages[index + 1] ?? null;
        const startFrame = (page.startMs / 1000) * fps;
        const endFrame = Math.min(
          nextPage ? (nextPage.startMs / 1000) * fps : Infinity,
          startFrame + (SWITCH_CAPTIONS_EVERY_MS / 1000) * fps,
        );
        const durationInFrames = endFrame - startFrame;

        if (durationInFrames <= 0) {
          return null;
        }

        return (
          <Sequence
            key={index}
            from={startFrame}
            durationInFrames={durationInFrames}
          >
            <CaptionPage page={page} />
          </Sequence>
        );
      })}
    </AbsoluteFill>
  );
};

帧换算公式是这套方案的技术核心:startFrame = (page.startMs / 1000) * fps。每页持续帧数取"下一页开始"与"本页最长停留时间"两者的较小值,并用 Math.min 钳制;durationInFrames <= 0 的页直接跳过(防止非法空 Sequence)。

3.5 空白保留:whiteSpace: "pre"

规则明确强调:字幕文本是空白敏感的text 字段中每个词前应包含空格,渲染时必须用 whiteSpace: "pre" 保留这些空白,否则连续单词会粘连在一起难以阅读。这一点同样体现在 OpenMontage 的组件实现中:CaptionOverlay.tsx 的渲染容器使用 whiteSpace: "pre-wrap"L106),并在每个词外包裹 display: "inline-block" + whiteSpace: "nowrap"L119-L120),保证换行只发生在词边界、单词不被截断。

3.6 独立组件拆分

规则要求把字幕逻辑放进独立组件、独立文件,不要与视频主组件混写。理由很实际:字幕组件需要同时消费 useCurrentFrame()(逐帧计算当前高亮词)与 useVideoConfig()(获取 fps),与主场景耦合会显著降低可维护性。OpenMontage 的 CaptionOverlay.tsx 正是这一要求的落地产物——它被 Explainer.tsxTalkingHead.tsxCinematicRenderer.tsx 等多个组合复用。

3.7 词级高亮(karaoke 效果)

每一页包含 tokens(词级时间戳数组),通过对比"当前绝对时间"与"词的 fromMs/toMs 窗口"来判断当前读到的词:

import { AbsoluteFill, useCurrentFrame, useVideoConfig } from "remotion";
import type { TikTokPage } from "@remotion/captions";

const HIGHLIGHT_COLOR = "#39E508";

const CaptionPage: React.FC<{ page: TikTokPage }> = ({ page }) => {
  const frame = useCurrentFrame();
  const { fps } = useVideoConfig();

  // Current time relative to the start of the sequence
  const currentTimeMs = (frame / fps) * 1000;
  // Convert to absolute time by adding the page start
  const absoluteTimeMs = page.startMs + currentTimeMs;

  return (
    <AbsoluteFill style={{ justifyContent: "center", alignItems: "center" }}>
      <div style={{ fontSize: 80, fontWeight: "bold", whiteSpace: "pre" }}>
        {page.tokens.map((token) => {
          const isActive =
            token.fromMs <= absoluteTimeMs && token.toMs > absoluteTimeMs;

          return (
            <span
              key={token.fromMs}
              style={{ color: isActive ? HIGHLIGHT_COLOR : "white" }}
            >
              {token.text}
            </span>
          );
        })}
      </div>
    </AbsoluteFill>
  );
};

高亮判定是一个左闭右开区间:token.fromMs <= absoluteTimeMs && token.toMs > absoluteTimeMs。注意时间换算:useCurrentFrame() 给出的是当前 Sequence 内部的相对帧,必须加上 page.startMs 得到绝对时间,才能与词级时间戳对齐。规则示例用 #39E508 作为高亮色(霓虹绿),实际项目中可替换为与主题色一致的强调色。

3.8 与视频内容同屏显示

字幕默认应叠放在视频内容之上,保证音画字三者同步;并且每段视频对应一份独立的字幕 JSON

<AbsoluteFill>
  <Video src={staticFile("video.mp4")} />
  <CaptionPage page={page} />
</AbsoluteFill>

3.9 OpenMontage 的增强实现

规则文件给出的是 API 层面的最小示例;OpenMontage 在 CaptionOverlay.tsx 中把同一套思想做成了可配置的生产组件,几处增强值得对照阅读:

  • 分页逻辑buildPages()L40-L58)以 wordsPerPage(默认 6)为硬分页阈值,同时尊重 pageBreakAfter 强制分页标记,与规则的 combineTokensWithinMilliseconds 策略互为补充;
  • 入场动画PageRendererspring()damping: 18, stiffness: 120)配合 interpolate 实现淡入 + 上移 20px 的入场(L75-L92),这符合 Remotion"动画由帧驱动、禁用 CSS transition"的规范(代码中显式注释 transition: "none");
  • 三态词色:当前词用 highlightColor(默认 #22D3EE),已读词用原色,未读词用 60% 透明度的原色(L121),并给高亮词叠加辉光 textShadow,提升复杂背景下的可读性;
  • CJK 适配wordSeparator 可传 ""(默认 " "),配合 pageBreakAfter 让中文字幕按小句分页,弥补规则方案对无空格语言的空缺。

四、导入字幕:从 .srt 到 Caption 的无缝转换

第三条路径是导入:如果你已有现成的 .srt 字幕文件(例如从剪辑软件或 subtitle_gen 工具导出),不必重新转写,直接用 parseSrt() 解析即可,对应 import-srt-captions.md

4.1 安装依赖

@remotion/captions 同时承担解析与渲染职责。不同包管理器对应不同安装命令:

npx remotion add @remotion/captions # If project uses npm
bunx remotion add @remotion/captions # If project uses bun
yarn remotion add @remotion/captions # If project uses yarn
pnpm exec remotion add @remotion/captions # If project uses pnpm

4.2 读取并解析 .srt

与 3.2 相同的异步加载骨架,只是把 response.json() 换成 response.text() + parseSrt()

import { useState, useEffect, useCallback } from "react";
import { AbsoluteFill, staticFile, useDelayRender } from "remotion";
import { parseSrt } from "@remotion/captions";
import type { Caption } from "@remotion/captions";

export const MyComponent: React.FC = () => {
  const [captions, setCaptions] = useState<Caption[] | null>(null);
  const { delayRender, continueRender, cancelRender } = useDelayRender();
  const [handle] = useState(() => delayRender());

  const fetchCaptions = useCallback(async () => {
    try {
      const response = await fetch(staticFile("subtitles.srt"));
      const text = await response.text();
      const { captions: parsed } = parseSrt({ input: text });
      setCaptions(parsed);
      continueRender(handle);
    } catch (e) {
      cancelRender(e);
    }
  }, [continueRender, cancelRender, handle]);

  useEffect(() => {
    fetchCaptions();
  }, [fetchCaptions]);

  if (!captions) {
    return null;
  }

  return <AbsoluteFill>{/* Use captions here */}</AbsoluteFill>;
};

parseSrt({ input: text }) 返回 { captions },其中每条字幕已规整为第一节的 Caption 结构(text/startMs/endMs)。规则还明确:远程 URL 同样受支持——只需把 staticFile("subtitles.srt") 换成 fetch("https://.../subtitles.srt") 这类远程地址,其余逻辑不变。解析完成后,字幕即可直接喂给 3.3 的 createTikTokStyleCaptions() 等所有 @remotion/captions 工具,实现"SRT 导入 → 分页渲染 → 词高亮"的完整链路。

4.3 仓库印证:SRT 在 OpenMontage 全链路中的角色

OpenMontage 中 SRT 不只是 Remotion 的输入,也作为 Remotion 不可用时的兜底媒介:

  • 转写工具的输出侧:技能文档 subtitle-sync.md 规定 subtitle_gen 工具可输出 SRT、VTT、Caption JSON 三种格式,其中 SRT 定位为"通用格式,兼容 FFmpeg、播放器与 YouTube 上传",Caption JSON 则专供"自定义渲染器做词级数据渲染"——与 Remotion 规则完全同构。
  • SRT 的解析侧RemotionCaptionBurn_srt_to_word_captions()L219-L261)用正则解析 SRT 时间轴(HH:MM:SS,mmm --> HH:MM:SS,mmm),把整条 cue 的时长按词数均分,产出词级 startMs/endMs,等效于规则中"导入后即可使用"的衔接点;工具还内置了 _ms_to_srt()L431-L437)反向把词级时间戳拼回 SRT,用于 FFmpeg 兜底烧录。
  • 时间戳正确性的测试保障:测试 test_subtitle_timestamps.py 专门覆盖了 SRT/VTT 时间戳的毫秒进位问题——例如 0.9999s 必须输出 00:00:01,000 而非非法的 00:00:00,1000,并验证进位能跨分、跨时正确传播。这类边界若不处理,生成的 SRT 会被 FFmpeg 的 subtitles 滤镜、VLC 等严格解析器拒绝,直接破坏"SRT 导入 → Remotion 渲染"与"SRT → FFmpeg 兜底"两条链路。

五、规则在生产管线中的落地:remotion_caption_burn

把三份规则串起来看,OpenMontage 把它们固化成了 tools/video/remotion_caption_burn.py 中的 RemotionCaptionBurn 工具(name = "remotion_caption_burn"capability = "subtitle"provider = "remotion"),其执行逻辑 execute()L443-L489)完整对应"生成 → 显示"两条规则:

  1. 输入二选一:segments(transcriber 的词级片段)或 srt_path,两者同时提供时 segments 优先;
  2. 词级数据统一转换为 WordCaption JSON(规则第一节的 Caption 结构在词级渲染场景的变体);
  3. 若检测到 Remotion 环境可用(npx 存在且找到 remotion-composer/ 下的 node_modules),把视频复制到 Remotion 的 public/talking-head/,连同字幕数据写入 public/demo-props/ 下的 props JSON,然后执行:
npx remotion render TalkingHead --props=... --fps=30 --codec=h264 --crf=18

渲染由 TalkingHead.tsx 组合承接,内部正是通过 CaptionOverlay 完成规则第三节的"Sequence 分页 + 词高亮"渲染(视频时长与分辨率由 ffprobe 动态探测后传入,保证烧录后画面尺寸不变)。

  1. 若 Remotion 不可用,则降级为 FFmpeg subtitles 滤镜烧录(L362-L429),按每页约 4 词把词级时间戳聚合成 SRT cue,配合 force_style 参数(白字、粗体、黑描边、底部居中 MarginV=100)保证可读性——这与 subtitle-sync.md 中关于 ASS force_style 的规范(如必须使用 8 位 &H00FFFFFF 颜色格式、竖屏 font_size 不超过 18 等)相互印证。

该工具的关键输入参数及默认值,可以看作规则在真实 API 中的参数化:

参数 默认值 说明
input_path / output_path 必填 输入视频与输出路径
segments transcriber 词级片段,优先于 srt_path
srt_path SRT 备选输入
words_per_page 4 每页词数(对应 wordsPerPage
font_size 52 字幕字号(fontSize
highlight_color #22D3EE 当前词高亮色(highlightColor
corrections 识别误词纠错字典,如 {"cloud": "Claude"}
force_ffmpeg false 强制走 FFmpeg 兜底

工具的 user_visible_verification 字段还给定了验收标准:字幕出现在画面底部、当前词按指定颜色高亮、字幕不遮挡人脸——这与规则"字幕叠放在视频内容之上、保持同步"的设计目标一一对应。

六、字幕工程的注意事项与最佳实践小结

综合规则文档与仓库实现,OpenMontage 的字幕规范可以浓缩为以下实践要点:

  1. 统一数据契约:一切字幕先落成 JSON,结构以 @remotion/captionsCaption 为准;text/startMs/endMs 是必填主干,timestampMs/confidence 由转写引擎填充。生产词级渲染时可用 WordCaption 这类变体,但字段语义保持一致。
  2. 生成链路:Whisper.cpp + tokenLevelTimestamps: true 获得词级时间戳 → toCaptions() 后处理 → 每片段独立 JSON 进 public/。没有词级时间戳时按词均分时长兜底,但要意识到精度下降。
  3. 显示链路useDelayRender 门控异步加载 → createTikTokStyleCaptions 按时间窗分页 → 每页一个 <Sequence>(帧号 = 毫秒 / 1000 × fps)→ whiteSpace: "pre" 保留空白 → 词级高亮用左闭右开区间判定;字幕逻辑必须独立成组件。
  4. 导入链路parseSrt({ input }) 一键把 .srt 转为 Caption[],之后与生成链路完全同构;注意毫秒进位这类时间戳边界问题(有专门回归测试兜底)。
  5. 格式与可读性:转写产生的是词级 JSON,烧录输出用 SRT 更通用;字幕应固定在画面底部区域(MarginV 不超过 100,竖屏字号受限),当前词高亮色需与主题保持对比度——OpenMontage 的主题对比度契约由测试 test_theme_text_contrast_contract.py 约束,保证任何主题下字幕文字都清晰可读。

以上五条,就是 OpenMontage 中 Remotion 字幕从"一段音频"到"带词高亮的成品视频"的完整规范路径;你可以在仓库中继续阅读 subtitles.md 及其三个子规则文档获取原始规则,对照 CaptionOverlay.tsxremotion_caption_burn.pysubtitle-sync.md 查看生产级实现细节。

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

项目优选

收起
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.16 K
2.78 K
kernelkernel
deepin linux kernel
C
34
18
docsdocs
暂无描述
Markdown
904
5.83 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
933
1.86 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
862
1.36 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.96 K
1.03 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.38 K
1.47 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
535
606
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
549
398
leetcodeleetcode
🔥LeetCode solutions in any programming language | 多种编程语言实现 LeetCode、《剑指 Offer(第 2 版)》、《程序员面试金典(第 6 版)》题解
Markdown
77
23