首页
/ Graphify 增量更新与重聚类完全指南:--update 增量重抽取与 --cluster-only 重聚类的完整工作流与源码解析

Graphify 增量更新与重聚类完全指南:--update 增量重抽取与 --cluster-only 重聚类的完整工作流与源码解析

2026-09-07 23:16:06作者:伍霜盼Ellen

Graphify 会把首次全量构建的产物持久化到 graphify-out/graph.jsonGRAPH_REPORT.mdgraph.html),而仓库是持续演进的:你每天会新增文件、修改代码、删除旧模块。--update--cluster-only 正是为“第二轮之后”的场景设计的两个子命令——前者只对发生变化的文件做增量重抽取并合并进既有图,后者在不改动任何节点/边的前提下对既有图重新聚类。本文以各平台技能的统一参考文档 update.md(及其 skillgen 产物 tools/skillgen/expected/graphify__skills__pi__references__update.md)为核心骨架,结合 graphify/detect.pygraphify/build.pygraphify/cli.py 等源码与测试,完整展开两套模式的每一步命令、参数语义与底层原理,让你(或你的 Agent)能安全、准确地维护一个长期不腐化的知识图谱。

一、两套模式定位:何时加载这份参考,何时触发

参考文档开宗明义地划定了它的使用边界:

Load this only when the user passed --update or --cluster-only. A first-time full build never reads this file.

也就是说,这份指南只在图已经存在的二次运行中生效;首次全量构建(bare path / URL / .)走的是主技能文档里的 Steps 1–9,与本参考无关。判断入口很简单:查看 graphify-out/graph.json 是否存在。如果存在且用户的请求是显式重建--update--cluster-only 或裸路径/URL),就走这里的流程;如果是关于代码库的自然语言提问,则应跳过重建直接走 graphify query 快速路径(见 skill-pi.md 中的 “Fast path — existing graph”)。

在交互式技能中,两套模式对应的入口命令是:

/graphify <path> --update        # incremental - re-extract only new/changed files
/graphify <path> --cluster-only  # rerun clustering on existing graph

两套模式的本质差别可以浓缩为一张对照表:

维度 --update(增量重抽取) --cluster-only(重聚类)
读取的中间产物 既有 graph.json + manifest 缓存 既有 graph.json(跳过 detect/extract)
是否改动节点与边 是:加入新文件、替换变更文件、修剪删除文件 否:节点/边保持原样
是否调用 LLM 语义抽取 仅在变更含文档/媒体文件时需要 仅在重新生成社区名时需要
产出 合并后的 graph.json,随后照常走 Step 4 起的分析与导出 新的 graph.jsonGRAPH_REPORT.mdgraph.html
对应 CLI Agent 驱动的脚本化流程(本参考文档) 一条自包含命令 graphify cluster-only .

注意一个容易混淆的点:仓库中 graphify/cli.py 里还有一条名为 update 的命令(见 cli.py),它通过 _rebuild_code 只对代码文件做 AST 级无 LLM 重建;而技能参考文档中的 --update 是面向 Agent 的完整增量语义流水线,可以处理文档、论文、图片、视频等所有类型的变化。本文聚焦后者,它才是参考文档的主体。

二、执行前的前置条件:.graphify_python 与输出目录

参考文档中的所有命令都通过 $(cat graphify-out/.graphify_python) 获取 Python 解释器路径。这个文件在每次构建时由主流程写入,指向创建虚拟环境时解析出的解释器。执行任何子命令(--update--cluster-onlyquery 等)前都应确认它存在;如果缺失(例如用户删除了 graphify-out/),需要先重新解析解释器再继续,否则后续 import graphify.* 全部失败。

所有中间状态文件都约定落在 graphify-out/ 下,其中点号前缀表示“运行期内部产物”,正常清理(Step 9)会删除它们,这也是 --cluster-only 不能重跑后续步骤的根本原因(见第五节)。贯穿全程的关键文件如下:

文件 含义 生产者 消费者
graphify-out/.graphify_incremental.json detect_incremental 的完整返回 增量探测 后续脚本
graphify-out/.graphify_detect.json 主流程 Steps 3A–6 读取的统一“本次运行状态” 增量包装脚本 Steps 3A–6
graphify-out/.graphify_old.json 合并前的旧图备份 cp 命令 diff 展示
graphify-out/.graphify_extract.json 抽取结果(增量模式下最终为“合并后全图”) 抽取/合并 Step 4 起的分析
graphify-out/graph.json 正式图产物 Step 4 导出 查询、导出

三、--update 增量重抽取:五段式脚本全解

增量更新的完整流程可以拆成五段:增量探测 → 状态落盘 → 变更分类 → 合并 → 落 manifest 与展示 diff。下面逐一展开,每一段都给出可直接执行的命令并解释其为何如此设计。

3.1 第一段:用 detect_incremental 找出真正变化的文件

$(cat graphify-out/.graphify_python) -c "
import sys, json
from graphify.detect import detect_incremental, save_manifest
from pathlib import Path

result = detect_incremental(Path('INPUT_PATH'))
new_total = result.get('new_total', 0)
print(json.dumps(result, indent=2, ensure_ascii=False))
Path('graphify-out/.graphify_incremental.json').write_text(json.dumps(result, ensure_ascii=False), encoding=\"utf-8\")
deleted = list(result.get('deleted_files', []))
if new_total == 0 and not deleted:
    print('No files changed since last run. Nothing to update.')
    raise SystemExit(0)
if deleted:
    print(f'{len(deleted)} deleted file(s) to prune.')
if new_total > 0:
    print(f'{new_total} new/changed file(s) to re-extract.'
)"

INPUT_PATH 替换为本次扫描根目录。detect_incremental 的定义位于 detect.py,其核心逻辑值得理解,因为它决定了“变化”的判定口径:

  • 内部先做一次全量 detect(),拿到当前磁盘上完整语料,再与上次运行保存的 manifest(mtime + 内容 hash)逐文件比对。
  • 没有历史 manifest 时:一切视为新增,new_total 等于全量文件数,deleted_files 为空——这是增量退化成全量的安全兜底。
  • 快路径:mtime 未变且 hash 匹配 → 判定为未变化,零磁盘 IO(仅 stat)。慢路径:mtime 变动后先比对 MD5,只有内容真正变了才判定为 changed(防止 touch 或无关元数据改动触发重抽取)。
  • 返回字典中 new_files 是按文件类型(code/document/paper/image/video 等)分组的变更子集,files完整语料deleted_files 是磁盘上已不存在的 manifest 行。源码还特别区分了 deleted vs excluded(见 detect.py):manifest 中有但本次扫描没有的行,若文件仍存活于磁盘,说明是被 .graphifyignore/.gitignore/--exclude 规则新排除的(记为 excluded_files),绝不能当成删除去清缓存——这个区分在合并阶段会被再次用到。

如果既没有新增/变更文件也没有删除,脚本直接 SystemExit(0),干净退出。

3.2 第二段:把增量状态改写为统一格式 .graphify_detect.json

$(cat graphify-out/.graphify_python) -c "
import json
from pathlib import Path
r = json.loads(Path('graphify-out/.graphify_incremental.json').read_text(encoding=\"utf-8\"))
Path('graphify-out/.graphify_detect.json').write_text(json.dumps({
    'files': r.get('new_files', {}),
    'all_files': r.get('files', {}),
    'total_files': r.get('new_total', 0),
    'total_words': r.get('total_words', 0),
    'skipped_sensitive': r.get('skipped_sensitive', []),
    'needs_graph': True,
}, ensure_ascii=False), encoding=\"utf-8\")"

这一步是格式对齐:主流程的 Steps 3A–6 会无条件读取 .graphify_detect.json,但它们期望看到的是全量构建那种“本次要处理的文件集合”。增量模式下必须喂给它增量语义的视图,关键在两个字段的错位使用:

  • files = new_files仅变更子集):驱动 Step 3A 的 AST 抽取和 Step 3B0 的缓存检查,保证只处理变化的内容;
  • all_files = files完整语料):供任何需要全库语境的步骤(如跨文件解析、全局符号表)使用。

needs_graph: True 告知下游需要产出图。这层“视图改写”是增量流程能在不改动主流程代码的前提下复用的关键设计。

3.3 第三段:变更分类——纯代码变更 vs 含语义内容变更

在决定执行哪条流水线之前,先探测“变更文件是否全部是代码文件”:

$(cat graphify-out/.graphify_python) -c "
import json
from pathlib import Path

result = json.loads(open('graphify-out/.graphify_incremental.json', encoding='utf-8').read()) if Path('graphify-out/.graphify_incremental.json').exists() else {}
code_exts = {'.py','.ts','.js','.go','.rs','.java','.cpp','.c','.rb','.swift','.kt','.cs','.scala','.php','.cc','.cxx','.hpp','.h','.kts','.lua','.toc','.f','.F','.f90','.F90','.f95','.F95','.f03','.F03','.f08','.F08'}
new_files = result.get('new_files', {})
all_changed = [f for files in new_files.values() for f in files]
code_only = all(Path(f).suffix.lower() in code_exts for f in all_changed)
print('code_only:', code_only)"

code_exts 覆盖了主流程可做确定性 AST 抽取的语言(Python/TS/JS/Go/Rust/Java/C++/C/Ruby/Swift/Kotlin/C#/Scala/PHP/Fortran/Lua 等)。随后根据 code_only 分支,这是整篇增量流程里第一个、也是最重要的成本决策点

分支 A:code_only 为 True——纯代码变更,完全跳过 LLM。 打印 [graphify update] Code-only changes detected - skipping semantic extraction (no LLM needed),然后:只对变更文件运行 Step 3A(AST 抽取)→ 整个跳过 Step 3B(语义子代理) → 直接进入合并与 Steps 4–8。代码文件的语法抽取是本地确定性的,不需要任何 token 开销,这也是增量更新“省 token、省时间”口号的主要来源。

分支 B:code_only 为 False——变更中含文档/论文/图片/视频。 这些文件的“语义理解”依赖 LLM,因此必须走完整 Steps 3A–3C。但其中有一个特殊的预置陷阱:如果 new_files['video'] 非空,必须先对视频文件执行转写(Step 2.5,对应参考文档 transcribe.md,仓库源码在 watch.py 中实现转写调度),然后把生成的转录文本路径files['video'] 移动到 files['document'] 后重写 .graphify_detect.json,再删除 video 键。否则原始 .mp4/.mp3 路径会被当作不可读媒体直接喂给语义子代理,导致空结果(对应 issue #1392)。

3.4 特殊分支:只有删除、没有新增文件时

if [ ! -f graphify-out/.graphify_extract.json ]; then
    echo '[graphify update] Only deletions -- creating empty extraction for merge.'
    $(cat graphify-out/.graphify_python) -c "
import json
from pathlib import Path
Path('graphify-out/.graphify_extract.json').write_text(json.dumps({'nodes':[],'edges':[],'hyperedges':[],'input_tokens':0,'output_tokens':0}), encoding='utf-8')
"
fi

当变更集里只有删除时,没有文件值得抽取,但合并步骤需要一个 extraction 输入才能触发“修剪”。这里以空 extraction(nodes/edges/hyperedges 全空)充当占位,让后续 build_merge 能纯粹地执行删除修剪。注意用 if [ ! -f ... ] 守卫——如果主流程已写过 extraction 则不覆盖。

3.5 核心合并段:build_merge 与三件“绝不可做错”的事

合并段是整个增量更新的心脏,代码较长,拆成注释逐段理解:

$(cat graphify-out/.graphify_python) -c "
import json
from pathlib import Path
from graphify.build import build_merge
from graphify.detect import save_manifest

# Load new extraction and incremental state
new_extraction = json.loads(Path('graphify-out/.graphify_extract.json').read_text(encoding=\"utf-8\"))
incremental = json.loads(Path('graphify-out/.graphify_incremental.json').read_text(encoding=\"utf-8\"))
deleted = list(incremental.get('deleted_files', []))

# prune_sources is ONLY for genuinely DELETED files. Changed/re-extracted files are
# handled by build_merge's replace-on-re-extract (#1344): every source_file in
# new_chunks is dropped from the base before merge, so old/stale nodes don't survive.
# Do NOT add 'changed' here: with root= passed, prune_set relativizes to the same base
# as the freshly merged nodes and would DELETE the re-extracted content.
prune = list(deleted) or None

# Use build_merge() — reads graph.json directly without NetworkX round-trip
# so edge direction (calls, implements, imports) is always preserved (#801).
# Pass root= so prune_sources (absolute paths from detect_incremental) are
# relativized to match the graph's relative source_file values; without it
# nothing is pruned and stale nodes accumulate on every update (#1361).
# directed=IS_DIRECTED: replace IS_DIRECTED with True if --directed was given, else
# False. Without it a --directed --update silently rebuilds undirected and collapses
# reciprocal A<->B edges (#1392).
G = build_merge(
    [new_extraction],
    graph_path='graphify-out/graph.json',
    prune_sources=prune,
    root='INPUT_PATH',
    directed=IS_DIRECTED,
)
print(f'[graphify update] Merged: {G.number_of_nodes()} nodes, {G.number_of_edges()} edges')"

build_merge 定义在 build.py,它只读不写 graph.json,返回合并后的 nx.Graph 由调用方落盘。源码 docstring 与实现揭示了几条关键语义,值得逐条说明:

① 变更文件是“替换”,不是“追加 + 去重”。 从源码看,凡是出现在 new_chunks 节点 source_file 里的文件,其旧节点/旧边会先从已加载基线中按 tier 分层删除再合并(replace-on-re-extract,#1344)。没有这层替换,旧版本的边/节点会永久残留(只靠去重只能消掉“完全相同”的重复项,无法消掉“旧版本独有”的内容)。这套替换机制还升级为按 tier 作用域(#2333/#2336):同一文件的 AST 产物与语义产物在图中是共存的两个层级,只重抽取其中一层时只替换那一层的旧贡献,绝不误删另一层。

prune_sources 只装“真正删除”的文件。 变更文件由替换机制处理,如果再把 changed 文件加进 prune,结合 root= 后的相对化会把刚重新抽取出来的新内容当场删掉(曾经引发 #1178,如今已由“替换优先于删除”的设计消解)。build_merge 内部同样有守卫:一个既在 new_chunks 又在 prune_sources 的文件,替换语义胜出,绝不修剪(#1796/#2012)。deleted 为空时传 None,避免空列表参与无意义的匹配。

root= 必须传,否则绝对路径永远匹配不上相对化的节点键。 detect_incremental 返回的删除路径是绝对的,而图中节点 source_file 是相对扫描根的。不传 root 会导致“什么都没修剪 + 陈旧节点每个更新周期都在累积”(#1361)。注意较新版本的 build_merge 已内置兜底:即使调用方漏传 root,也会从既有 graph.json 记录的扫描根推导出有效根(#1571),但显式传 root='INPUT_PATH' 仍是最稳做法——它与主流程全量构建使用同一基准,保证两边永不漂移。

directed= 必须与原图一致。 占位符 IS_DIRECTED 要按原构建是否带 --directed 替换成 True/False。如果原图是有向的而合并时未传 directedbuild_merge 会静默按无向重建,把互为反向的 A→BB→A 折叠成一条边(#1392)。源码对 directed=None 的处理是“继承磁盘图自身的方向标志”(#2342),显式传值与磁盘冲突时以显式值为准。

⑤ 为什么用 build_merge 而不是 NetworkX round-trip? 源码注释明确说明直接读 graph.json 避免了 NetworkX 往返,因此 calls/implements/imports边的方向信息在合并全程不丢失(#801)。同理,合并结果的 hyperedges 取自 G.graph['hyperedges']——它同时携带旧 graph.json 与新 extraction 的超边(build_merge 会合并两者)。若只回退到 new_extraction,上一次运行遗留的超边会被悄悄丢弃(#801)。

3.6 合并结果回写与 manifest 落盘

$(cat graphify-out/.graphify_python) -c "
import json
from pathlib import Path
from graphify.build import build_merge
from graphify.detect import save_manifest

merged_out = {
    'nodes': [{'id': n, **d} for n, d in G.nodes(data=True)],
    'edges': [
        # Explicit source/target last so they win over any stale attrs in d.
        {**{k: val for k, val in d.items() if k not in ('_src', '_tgt', 'source', 'target')},
         'source': d.get('_src', u), 'target': d.get('_tgt', v)}
        for u, v, d in G.edges(data=True)
    ],
    # G.graph['hyperedges'] holds hyperedges from both existing graph.json
    # and new_extraction (build_merge combines them).
    'hyperedges': list(G.graph.get('hyperedges', [])),
    'input_tokens': new_extraction.get('input_tokens', 0),
    'output_tokens': new_extraction.get('output_tokens', 0),
}
Path('graphify-out/.graphify_extract.json').write_text(json.dumps(merged_out, ensure_ascii=False), encoding=\"utf-8\")
print(f'[graphify update] Merged extraction written ({len(merged_out[\"nodes\"])} nodes, {len(merged_out[\"edges\"])} edges)')

from graphify.cli import _stamped_manifest_files
_manifest_files = _stamped_manifest_files(incremental['files'], new_extraction, Path('INPUT_PATH'))
_sem_types = ('document', 'paper', 'image')
_dispatched = {f for t, fl in incremental.get('new_files', {}).items() if t in _sem_types for f in fl}
_stamped = {f for fl in _manifest_files.values() for f in fl}
_cleared = _dispatched - _stamped
_scan = {f for fl in incremental['files'].values() for f in fl}
save_manifest(_manifest_files, root='INPUT_PATH', scan_corpus=_scan, clear_semantic=_cleared or None)
print('[graphify update] Manifest saved.')"

这段完成两件事,且顺序有讲究:

回写合并图到 .graphify_extract.json 这样 Step 4(社区发现与报告生成)看到的就是“已含本次增量”的完整图,无需感知合并细节。边数据的构造刻意把 source/target 放到 dict 展开的最后,确保它们覆盖掉节点属性里可能残留的陈旧 source/target 字段。

保存 manifest,供下次 --update 做差异基准。 注意三点细节(save_manifest 定义见 detect.py_stamped_manifest_filescli.py):

  1. 只 stamp 真正产出了输出的语义文件(_stamped_manifest_files 会过滤掉“chunk 抽取失败/被截断”的文件)。一个变更过的文档若本次 chunk 失败,就必须保持未 stamp,否则下次 --update 会认为它已处理完而永不重试,其内容就永远丢失了(#2015/#933)。_dispatched - _stamped 得到“本次派发但未 stamp”的文件集合,通过 clear_semantic 把它们的 semantic_hash 清空,强制下次重新排队(#1948)。
  2. root= 与合并段保持一致,manifest 键写成相对扫描根的 posix 形式,从而跨机器/跨克隆位置可移植(#777/#1417)——否则一次 git clone 搬家后,所有缓存匹配全部失效。
  3. scan_corpus 传完整语料incremental['files'] 的原始全集)。这是 #1908 的机制:本轮起被排除规则踢出扫描范围、但仍在磁盘上的文件,其 manifest 行应被丢弃而不是永远伪装成删除;未触及的行则原样保留。

3.7 合并前的图备份与更新后的图 diff

合并会就地覆盖旧图,因此参考文档要求在任何合并动作前先备份:

cp graphify-out/graph.json graphify-out/.graphify_old.json

完成合并与 Step 4 之后,展示增量结果给用户看:

$(cat graphify-out/.graphify_python) -c "
import json
from graphify.analyze import graph_diff
from graphify.build import build_from_json
from networkx.readwrite import json_graph
import networkx as nx
from pathlib import Path

# Load old graph (before update) from backup written before merge
old_data = json.loads(Path('graphify-out/.graphify_old.json').read_text(encoding=\"utf-8\")) if Path('graphify-out/.graphify_old.json').exists() else None
new_extract = json.loads(Path('graphify-out/.graphify_extract.json').read_text(encoding=\"utf-8\"))
G_new = build_from_json(new_extract, directed=IS_DIRECTED)

if old_data:
    G_old = json_graph.node_link_graph(old_data, edges='links')
    diff = graph_diff(G_old, G_new)
    print(diff['summary'])
    if diff['new_nodes']:
        print('New nodes:', ', '.join(n['label'] for n in diff['new_nodes'][:5]))
    if diff['new_edges']:
        print('New edges:', len(diff['new_edges']))"

graph_diff 定义在 analyze.py:它对比两图快照,返回 new_nodes/removed_nodes/new_edges/removed_edges 与一句话 summary(形如 "3 new nodes, 5 new edges, 1 node removed")。注意有向/无向差异会影响边键的计算:有向图用 (u, v, relation),无向图用排序后的 (min(u,v), max(u,v), relation)。展示完 diff 后清理备份:rm -f graphify-out/.graphify_old.json。随后照常对合并后的图执行 Steps 4–8(聚类、命名、报告、导出),增量更新到此闭环。

四、--cluster-only:只重聚类,不碰抽取

参考文档对 --cluster-only 的描述极其简练:跳过 Steps 1–3,在既有图上重跑聚类

graphify cluster-only .

在技能语境下,这通常对应 Agent 场景:聚类参数或社区命名模型变了、用户对上一轮的分组不满意想重分、或只是想要一份更新鲜的 GRAPH_REPORT.md。CLI 层对 cmd in ("cluster-only", "label") 的处理见 cli.py

graphify cluster-only .自包含的:它读取既有 graph.json,重新做社区发现、重新生成社区名,并直接产出新的 GRAPH_REPORT.mdgraph.jsongraph.html,不需要也不允许依赖任何抽取阶段的中间产物。

不要重跑 Steps 5–9。 这是最容易踩的坑:Steps 5–9 会读取 .graphify_extract.json.graphify_detect.json.graphify_analysis.json 等文件,而一次正常构建的清理步骤(Step 9)已经把中间产物删掉了——直接重跑必然抛 FileNotFoundError(#1392)。cluster-only 完成后的正确动作只有一个:像平时一样向用户呈现刷新后的 GRAPH_REPORT.md 摘要。

五、常见陷阱速查:每条坑背后都有 issue 与源码

参考文档中散布着大量 “为什么必须这样写” 的注释,多数关联到具体 issue。整理成速查表,便于 Agent 在执行时对照自查:

陷阱 正确做法 依据
把变更文件加进 prune_sources 只放 deleted_files;变更文件交给 replace-on-re-extract #1344,#1178,build.py
合并时漏传 root= 传与全量构建相同的扫描根 #1361,#1571
--directed 图做增量却传 directed=False 原图带 --directed 就传 True,否则 False #1392,#2342
hyperedges 只取 new_extraction 从合并后 G.graph['hyperedges'] #801
给失败的语义文件 stamp _stamped_manifest_files 过滤,仅 stamp 成功者 #2015,#933,#1948
把被排除文件当删除 detect_incremental 区分 deleted_filesexcluded_files #1908,detect.py
--cluster-only 后重跑 Steps 5–9 中间产物已被 Step 9 清理,会 FileNotFoundError #1392
视频变更不转写直接喂子代理 先跑 transcribe,再把转录路径并入 files['document'] #1392

这些行为多数有测试锁定:增量判定与 mtime 边界的正确性由 tests/test_incremental.pytests/test_incremental_mtime_collision.py 覆盖;合并后超边不丢失在 tests/test_dedup_remaps_hyperedges.py 等测试中验证;陈旧节点修剪见 tests/test_stale_prune.py;Office/媒体增量相关见 tests/test_office_incremental.py。对照测试读源码,是排查增量行为异常最直接的路径。

六、总结:把增量心智模型固化下来

  • --update 的本质是 “用磁盘现状对旧图做一次收敛”:新增文件并入、变更文件按 tier 替换、删除文件修剪、失败的文件保持“脏”状态以便重试——所有机制都服务于同一个目标:图永远等于“对当前磁盘语料重新全量构建”会得到的结果,但只支付变化的代价
  • --cluster-only 的本质是 “只换分组,不换内容”:它是纯下游的重算,因此在正确构建过 graph.json 的前提下永远安全、可重复。
  • 增量流程能复用主流程的 Steps 3A–6,靠的是 .graphify_detect.json 这一层“视图改写”——把增量探测结果伪装成主流程期望的统一状态格式。

理解上述机制后,无论你是在交互式 Agent 会话里执行 /graphify <path> --update,还是手动用 graphify cluster-only . 刷新聚类结果,都能预判每一步的副作用与失败模式。更完整的入口级说明(Steps 编号体系与 Usage)见 graphify/skill-pi.md,各平台的同构参考版本可以从 graphify/skills/pi/references/update.md 出发按目录对照查阅。

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

项目优选

收起
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.8 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
595
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
918
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.6 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.01 K
517
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
389