Post

HKUDS025: OpenGraph 作为 Open Graph Foundation Model 与 Zero-Shot Graph Generalization Layer

HKUDS025: OpenGraph 作为 Open Graph Foundation Model 与 Zero-Shot Graph Generalization Layer

这是 PENGYI_HKUDS_STUDYMAP 的第二十六篇。

1
HKUDS025 -> OpenGraph

上一篇 HKUDS024 看的是 GraphAgent

1
GraphAgent -> agentic graph language assistant

这一篇继续图智能主线,进入 OpenGraph

1
OpenGraph -> open graph foundation model

这两篇要连起来看。

GraphAgent 关注的是:

1
2
3
4
5
user instruction
  -> task planning
  -> graph generation
  -> graph tokenizer
  -> graph-language model execution

OpenGraph 关注的是:

1
2
3
4
5
graph itself
  -> unified graph tokenizer
  -> topology-aware projection
  -> scalable graph transformer
  -> zero-shot graph learning

也就是说,GraphAgent 更像把 graph 放进 agent 和 language model 工作流;OpenGraph 更像把 graph model 本身做成可以跨数据集泛化的 foundation model。

这对我们非常关键。因为未来的 Research OS / Quant OS 不是只有一个固定图,而是会不断遇到新图:

1
2
3
4
5
6
7
paper graph
repo dependency graph
author-lab-project graph
factor-data-risk graph
asset-event-industry graph
client-company-credit graph
market-regime-transition graph

如果每换一个图都要重新训练一个 GNN,系统就不够 open。OpenGraph 想解决的正是这个问题:

1
让图模型对 unseen graph data 也有 zero-shot generalization。

Local Snapshot

这次阅读的是本地 HKUDS 工作区里的 OpenGraph

ItemValue
repoOpenGraph
remotehttps://github.com/HKUDS/OpenGraph.git
branchmain
local head152b8b6
full commit152b8b6439a281e46bd569a92c69f0c59f98a902
latest local commit date2024-10-11 12:10:39 +0800
latest local commitUpdate README.md
statusclean, synced with origin/main after fetch
paperOpenGraph: Towards Open Graph Foundation Models, EMNLP 2024
authorsLianghao Xia, Ben Kao, Chao Huang
tracked files by git ls-files116
Python files18
markdown files1
notebooks0
main folderslink_prediction, node_classification, graph_generation, datasets, Models, History, imgs
dataset foldersgen0, gen1, gen2, ml1m, ml10m, collab, amazon-book, ddi, cora, citeseer, pubmed
environment in READMEPython 3.10.13, torch 1.13.0, numpy 1.23.4, scipy 1.9.3
package metadatano requirements.txt, no pyproject.toml, no setup.py
pretrained model noteModels/readme points to a Google Drive folder
validationpy -m compileall -q link_prediction node_classification graph_generation passed
runtime checknot run locally because runtime needs CUDA, unzipped datasets, optional pretrained models, and undocumented deps such as setproctitle / torch_geometric

一句话先行:

1
2
OpenGraph 用 LLM 生成合成图数据,用统一 graph tokenizer 把不同图投影到共同 latent space,
再用 topology smoothing + anchor-sampled graph transformer 学到跨图可迁移的图表示。

它的核心不是“在某个图上做高分”,而是:

1
在训练图之外的新图上保持 zero-shot graph learning 能力。

它解决什么问题

传统 GNN 有一个很大的限制:

1
每个图的数据分布、节点数量、边结构、节点特征、任务标签空间都可能不同。

比如:

1
2
3
4
5
MovieLens 是 user-item interaction graph
Amazon-Book 是 user-book interaction graph
OGBL-Collab 是作者合作图
DDI 是 drug-drug interaction graph
Cora / Citeseer / Pubmed 是 citation graph

如果一个模型在一个图上训练,它通常不能自然迁移到另一个图。原因包括:

1
2
3
4
5
6
node id 不共享
feature space 不共享
graph scale 不同
degree distribution 不同
homophily / heterophily 不同
task label space 不同

OpenGraph 的目标是把图学习推向 foundation model:

1
2
不为每个图从零训练一个专用模型,
而是训练一个能适配不同 unseen graph 的开放图基础模型。

README 里对目标的表达很直接:

1
distilling zero-shot graph generalizability from LLMs

这里的关键是 zero-shotgeneralizability。这和我们做 Research OS / Quant OS 很贴近,因为我们未来面对的图也会不断变:

1
2
3
4
今天是 HKUDS repo graph
明天是 LLMQuant project graph
后天是 WorldQuant factor graph
再之后是 A-share asset-event graph

系统不能每次换图就重新开始。

总体结构

OpenGraph 可以拆成四层:

LayerCodeRole
LLM Data Generationgraph_generation用 LLM 生成合成图数据,缓解真实图数据稀缺
Unified Graph TokenizerInitialProjector把不同图投影到统一 latent dimension
Topology EncoderTopoEncoder用 adjacency smoothing 注入局部拓扑
Scalable Graph TransformerGraphTransformer / GTLayer用 anchor sampling 做全局依赖建模
Task Heads / Evaluationlink_prediction, node_classification评估 link prediction / node classification 的跨图泛化

主链路可以写成:

1
2
3
4
5
6
graph adjacency
  -> initial projection / tokenizer
  -> topology smoothing
  -> anchor-sampled graph transformer
  -> node embeddings
  -> link prediction or node classification

如果是预训练数据构造,则是:

1
2
3
4
5
6
7
LLM prompts
  -> entity/category tree
  -> instance number estimation
  -> text embedding
  -> Gibbs-style human-item relation generation
  -> adjacency matrix
  -> generated graph dataset

所以它不是一个纯模型仓库,也不是一个纯数据生成仓库,而是两者合在一起:

1
synthetic graph data generation + graph foundation model training/evaluation

Component 1: LLM-Enhanced Graph Data Generation

目录:

1
graph_generation

README 给出的生成流程是:

1
2
3
4
5
python itemCollecting_dfsIterator.py
python instance_number_estimation_hierarchical.py
python embedding_generation.py
python human_item_generation_gibbsSampling_embedEstimation.py
python make_adjs.py

这条链路大致是:

1
2
3
4
5
6
1. 用 LLM 从一个场景和根实体开始枚举子类别。
2. 构造层级 entity tree。
3. 估计每个类别应该生成多少实例。
4. 用 text embedding 表示每个 item。
5. 用 Gibbs sampling 风格方法生成 human-item interactions。
6. 生成 train / valid / test adjacency matrices。

默认示例是:

1
2
3
entity   = products
scenario = e-commerce platform like Amazon
depth    = 3

这会生成电商商品类别树和交互数据,最后落到:

1
gen_results/datasets/gen_data_ecommerce

这一步是 OpenGraph 的一个关键思想:

1
用 LLM 的世界知识补足图数据稀缺问题。

对我们来说,这很有启发。因为量化研究里也会有数据稀缺和场景稀缺:

1
2
3
4
某些市场 regime 样本少
某些风险事件样本少
某些新行业图关系没有足够历史
某些事件-资产传播路径很难直接标注

短期不能把 LLM 生成的数据直接当真实金融信号,但可以用它生成:

1
2
3
4
5
scenario graph
event taxonomy
risk propagation template
factor failure mode taxonomy
company-supply-chain schema

这些可以成为 Research OS 的结构化先验。

Component 2: Unified Graph Tokenizer

OpenGraph 的 graph tokenizer 主要体现在:

1
InitialProjector

位置:

1
2
link_prediction/model.py
node_classification/model.py

它要解决的问题是:

1
不同 graph 没有共享 node vocabulary,也不一定有统一 feature space。

所以它先把图投影到固定维度:

1
args.latdim = 1024

支持几种初始化方式:

1
2
3
4
5
uniform
lowrank_uniform
svd
both
id

默认是:

1
proj_method = svd

SVD 版本会对 adjacency 做低秩分解,再生成 node embedding:

1
adj -> svd_lowrank -> U / S / V -> fixed-dimensional initial embeddings

这就是它的“统一 graph tokenizer”雏形:

1
2
3
不管原图来自哪个数据集,
先把节点映射到统一 latent dimension,
再让后续 encoder 处理。

这和语言模型的 tokenizer 有一点类比:

1
2
3
4
5
text tokenizer:
  arbitrary text -> token ids / embeddings

graph tokenizer:
  arbitrary graph -> initial node embeddings

但图更难,因为 graph 没有天然词表。OpenGraph 通过 topology-aware projection 来做适配。

Component 3: Topology Encoder

TopoEncoder 做的是 adjacency smoothing。

代码逻辑很直接:

1
2
3
4
5
embeds = LayerNorm(embeds)
for i in range(args.gnn_layer):
    embeds = sparse_adj @ embeds
    embeds_list.append(embeds)
embeds = sum(embeds_list)

默认:

1
gnn_layer = 3

这意味着模型会把 1-hop、2-hop、3-hop 的结构信息平滑进 node embedding。

README 的 graph tokenizer study 也强调:

1
Adjacency smoothing is important.

如果不做 smoothing,单纯的初始投影很难表达图拓扑。对跨图泛化来说,topology smoothing 是非常关键的 inductive bias:

1
2
不是记住某个图的节点,
而是学习可迁移的拓扑模式。

对量化系统来说,这个思想很有用。比如资产图里:

1
2
3
资产 A 受同产业链节点影响
资产 B 与同主题事件相邻
资产 C 与同资金流/风格因子相邻

邻接 smoothing 本质上是在说:

1
一个节点的表示应该吸收邻居和多阶邻域的信息。

这非常适合行业链、供应链、新闻事件传播、风险扩散和 factor family graph。

Component 4: Scalable Graph Transformer

GraphTransformer 由多个 GTLayer 组成:

1
2
3
gt_layer = 4
head     = 4
anchor   = 256

标准 Transformer 如果对所有节点做全量 attention,复杂度会接近:

1
O(N^2)

大图上会很贵。OpenGraph 的 GTLayer 做了 anchor sampling:

1
2
3
4
1. 随机选 anchor nodes。
2. anchor nodes attend to all nodes。
3. all nodes attend back to anchor nodes。
4. 再过 feed-forward 和 layer norm。

代码里是:

1
2
3
anchor_embeds = self._pick_anchors(embeds)
anchor_embeds = MultiheadAttention(anchor, embeds, embeds)
embeds        = MultiheadAttention(embeds, anchor, anchor)

这相当于用一组 sampled anchors 作为信息瓶颈,把全局上下文压缩后再广播回所有节点。

README 的 sampling study 也说明:

1
2
sampling techniques help memory and time cost,
and token sequence sampling can even help performance.

这对我们也很重要。因为 Research OS / Quant OS 的图会越来越大:

1
2
3
4
几百篇 paper
几千个 repo / functions / classes
几万个 factor result
几万条 news / event / asset links

如果每次都全图 attention,系统很快不可用。Anchor sampling 给了一个实用方向:

1
用关键节点 / sampled anchors / representative nodes 做全局压缩。

目录:

1
link_prediction

这是 OpenGraph 的预训练和推荐/链接预测主线。

README 复现实验的命令包括:

1
2
3
4
cd link_prediction/
python main.py --load pretrn_gen1 --epoch 0
python main.py --load pretrn_gen0 --tstdata amazon-book --epoch 0
python main.py --load pretrn_gen2 --tstdata ddi --epoch 0

预训练命令包括:

1
2
3
python main.py --save pretrn_gen1
python main.py --trndata gen0 --tstdata amazon-book --save pretrn_gen0
python main.py --trndata gen2 --tstdata ddi --save pretrn_gen2

main.py 里默认:

1
2
trn_datasets = ['gen1']
tst_datasets = ['ml1m', 'ml10m', 'collab']

这说明它希望用生成图 gen1 去迁移到真实图 ml1m / ml10m / collab

训练逻辑:

1
2
3
4
5
6
7
positive edge: (anchor, positive)
negative edge: (anchor, negative)
mask positive edge from adjacency
topology encode
graph transformer
dot product score
contrastive / softmax-like loss

评测指标:

1
2
Recall@K
NDCG@K

这条线对量化有直接映射:

1
link prediction = 预测两个节点之间未来是否应该连接。

在金融里可以类比:

1
2
3
4
5
6
asset-event link
factor-asset link
company-supply-chain link
theme-stock link
risk-factor link
research-paper-method link

尤其是 factor research:

1
2
3
一个新因子是否应该连接某类资产?
一个风险事件是否会影响某个行业?
一个策略是否和某类 market regime 相关?

这些都可以被抽象成 graph link prediction。

Node Classification 主线

目录:

1
node_classification

README 给出的测试命令:

1
2
3
4
cd node_classification/
python main.py --load pretrn_gen1 --tstdata cora
python main.py --load pretrn_gen1 --tstdata citeseer
python main.py --load pretrn_gen1 --tstdata pubmed

节点分类分支复用了同一套核心模块:

1
2
3
4
5
InitialProjector
TopoEncoder
GraphTransformer
Masker
OpenGraph

不同点在于任务输出。pred_for_node_test 会:

1
2
3
4
1. 重新跑全图 embedding。
2. 取待分类 node embeddings。
3. 取最后 class_num 个 class embeddings。
4. 用 dot product 选择最匹配类别。

也就是说,node classification 被转成:

1
node embedding -> nearest / highest-score class embedding

这和 link prediction 的形式很统一:

1
2
3
4
5
link prediction:
  node A embedding dot node B embedding

node classification:
  node embedding dot class embedding

这种统一是 foundation model 思路里很重要的一点:

1
尽量把不同 graph tasks 转换成统一的 embedding scoring 问题。

对 Research OS 来说,这可以映射成:

1
给一个 paper/repo/project/factor 自动分类到某个 research theme。

对 Quant OS 来说,可以映射成:

1
给一个 factor 自动分类到 value / momentum / quality / sentiment / event / risk / liquidity family。

Evaluation Results

README 展示了几组结果:

1
2
3
4
Overall Generalization Performance
Pre-training Dataset Study
Graph Tokenizer Study
Sampling Techniques Study

结论可以概括为:

1
2
3
4
5
6
1. OpenGraph 在 0-shot setting 下表现强于一些 1-shot / 5-shot baselines。
2. 生成数据里的 Norm / Loc / Topo 技术对性能有正向作用。
3. 预训练数据的相关性很重要,例如 ML-10M 对 ML-1M / ML-10M 迁移更好。
4. adjacency smoothing 很重要。
5. topology-aware projection 比 one-hot / random / degree 替代方案更好。
6. anchor sampling 同时改善 memory / time cost,并可能改善 performance。

这里最值得我们吸收的是第三点:

1
2
foundation model 不是说预训练数据随便来都行。
预训练图和目标图之间仍然需要 domain relevance。

对应到量化:

1
2
用电商推荐图预训练,不一定能直接迁移到股票事件图。
用供应链/行业/主题/资产相关性图预训练,可能更适合金融图任务。

所以未来如果我们做 Quant Graph Foundation Layer,预训练图应该围绕:

1
2
3
4
5
6
7
asset co-movement
industry hierarchy
supply chain
company-event links
factor-family links
news-topic-stock links
portfolio exposure graph

而不是随便拿一个通用图。

和 GraphAgent 的区别

GraphAgent 和 OpenGraph 都在图智能主线,但系统位置不同。

Project更像什么输入核心输出
GraphAgentagentic graph-language assistantuser instruction + text / graphgraph-conditioned answer / prediction
OpenGraphgraph foundation modelgraph adjacency / generated graph datazero-shot transferable node embeddings

GraphAgent 解决的是:

1
如何让 agent 构图、理解任务、调用 graph-language model 完成预测或生成。

OpenGraph 解决的是:

1
如何让 graph model 本身跨图泛化。

如果两者结合,合理结构是:

1
2
3
4
5
GraphAgent:
  负责 task planning / graph generation / language interaction。

OpenGraph:
  负责 graph encoding / zero-shot topology representation。

放进我们的系统,可以是:

1
2
3
4
Research OS / Quant OS
  -> GraphAgent-style planner decides what graph task to run
  -> OpenGraph-style encoder computes graph representations
  -> LLM writes explanation / diagnosis / next plan

这就是 HKUDS024 -> HKUDS025 的连续价值。

对 Pengyi Research OS 的意义

Research OS 未来会有很多图:

1
2
3
4
5
6
7
project graph
paper citation graph
method dependency graph
repo architecture graph
person-lab-institution graph
learning-topic graph
PR opportunity graph

一开始我们可以用简单 JSON / NetworkX / SQLite 存储它们。但随着对象变多,问题会变成:

1
2
3
4
如何对新 project graph 做分类?
如何预测两个 idea 是否应该连接?
如何判断某个 repo 属于哪条主线?
如何发现尚未连接但应该连接的 paper / method / project?

这就是 OpenGraph 可以启发的地方。

它告诉我们:

1
2
Research OS 的 graph layer 不应该只是存图。
它最终应该能做 graph representation learning。

短期我们先做轻量版:

1
2
3
4
5
6
node schema
edge schema
graph extraction
graph query
graph visualization
graph-to-prompt

中期可以做:

1
2
3
4
node embedding
link prediction
theme classification
research opportunity recommendation

长期再考虑:

1
OpenGraph-style graph foundation model for research objects

对 Pengyi Quant Research OS 的意义

Quant OS 的图结构更明显。

可以直接建成:

1
2
3
4
5
6
7
8
9
10
11
asset graph:
  stock -> industry -> theme -> supply chain -> macro exposure

factor graph:
  factor -> data source -> universe -> horizon -> risk -> backtest result

event graph:
  event -> company -> industry -> asset -> price reaction

portfolio graph:
  holding -> exposure -> constraint -> risk source -> pnl attribution

OpenGraph 的 zero-shot graph generalization 对量化很关键,因为金融图一直在变:

1
2
3
4
5
6
新行业出现
新主题出现
新政策事件出现
新公司上市
新因子被发现
旧关系失效

如果 graph model 只能在固定资产池里工作,就不够好。我们需要的是:

1
new graph, still usable.

这可以变成我们自己的 Quant Graph Layer:

1
2
3
4
5
6
worldquant factor formulas
  -> factor family graph
  -> factor-asset relation graph
  -> factor-risk relation graph
  -> factor-failure graph
  -> next factor recommendation

尤其是我们后面要整理 WorldQuant 因子库,不能只做列表。更好的方式是:

1
2
3
每个 factor 都成为 graph node。
每个 formula component / operator / data field / decay / neutralization 都成为 relation。
每个 backtest result / failure mode / risk exposure 都成为 relation。

然后我们才能问:

1
2
3
4
哪些 factor family 在成本后更容易失效?
哪些 operator 组合经常带来 look-ahead / liquidity bias?
哪些 data field 和哪些 horizon 最相关?
哪些失败案例可以合成新的 hypothesis?

OpenGraph 不是直接解决这些问题,但它给了底层路线:

1
把 graph 变成可泛化的表征空间。

我们怎么吸收

不要一开始就复刻 OpenGraph 的完整训练。

我们的 v0 应该是:

1
2
3
4
5
1. 先定义 Research OS / Quant OS 的 graph schema。
2. 把现有 HKUDS / LLMQuant 文章抽成 nodes and edges。
3. 建一个简单 graph store。
4. 做 graph query 和 graph visualization。
5. 做 simple link prediction / node classification demo。

一个实际 v0 可以是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
nodes:
  Project
  Method
  Dataset
  Task
  Paper
  Factor
  Risk
  Backtest
  PR_Opportunity

edges:
  uses
  improves
  belongs_to
  depends_on
  evaluates_on
  connects_to_quant_os
  has_failure_mode
  suggests_next

然后做两个小任务:

1
2
3
4
5
1. node classification:
   给一个新 project 自动分到 RAG / Agent / Graph / Quant / Research Engineering。

2. link prediction:
   预测某个 project 是否应该连接到某个 Quant OS module。

这会比一开始训练大模型更实际,也更贴近我们的公开 portfolio。

可以提 PR 的地方

OpenGraph 目前有一些具体、可落地的小改进点。

第一,仓库没有 requirements.txt / environment.yml / pyproject.toml,README 只列了几个核心版本:

1
2
3
4
python==3.10.13
torch==1.13.0
numpy==1.23.4
scipy==1.9.3

但代码还用到:

1
2
3
4
5
6
setproctitle
torch_geometric
sklearn
openai
tiktoken
networkx

可以补一个最小 requirements.txtenvironment.yml

第二,graph_generation/Utils.pygraph_generation/itemCollecting_dfsIterator.py 里有硬编码占位 API key:

1
2
openai.api_key = "xx-xxxxxx"
openai.api_key = "xxxxxx"

更好的做法是从环境变量读取:

1
OPENAI_API_KEY

第三,OpenAI Python SDK 写法是旧版:

1
2
openai.ChatCompletion.create
openai.Embedding.create

如果用户装新版 openai,可能会出兼容问题。可以在 requirements 里 pin 旧版,或者迁移到新版 client。

第四,link_prediction/model.pynode_classification/model.py 里有重复模型实现,两个文件大段几乎一致。可以抽到共享模块,减少维护成本。

第五,OpenGraph.forward 里调用:

1
self.topoEncoder(adj, initial_projector(), user_num)

TopoEncoder.forward 的签名是:

1
forward(self, adj, embeds)

目前主训练和测试路径用的是 cal_loss / pred_for_test / pred_for_node_test,绕开了 OpenGraph.forward,所以 compileall 不会报错。但如果外部用户直接调用 model(adj, projector, user_num),可能会触发 TypeError。这适合提一个小 PR。

第六,代码大量默认 CUDA:

1
2
args.devices = ['cuda:0', 'cuda:0']
.cuda()

README 可以明确 GPU requirement,或者代码里增加 CPU fallback。

第七,README 有一些拼写和文档小问题:

1
2
3
4
5
achives -> achieves
Suprisingly -> Surprisingly
gaphs -> graphs
wheter -> whether
inadverdently -> inadvertently

这类小 PR 很适合先建立 contributor 关系。

第八,Models/readme 只有 Google Drive 链接,没有说明具体文件名、放置路径、校验信息。可以补一个更明确的模型下载说明。

第九,部分数据需要手动 unzip。可以补一个小脚本:

1
scripts/prepare_data.py

自动解压 datasets 下的 .zip 文件,并检查缺失文件。

这些都是比较合适的贡献入口,不需要改论文核心算法。

和我们的主线连接

GraphAgent 和 OpenGraph 这两篇合起来,给了我们一个清晰判断:

1
2
Research OS / Quant OS 的图层不应该只停留在知识图谱存储。
它应该逐步走向 graph reasoning 和 graph representation learning。

可以分三阶段:

1
2
3
4
5
6
7
8
Stage 1: Graph Memory
  notes / papers / repos / factors -> nodes and edges

Stage 2: Graph Retrieval / Reasoning
  graph query, path search, relation explanation, graph-to-prompt

Stage 3: Graph Foundation Layer
  node classification, link prediction, cross-graph transfer, zero-shot graph learning

OpenGraph 属于 Stage 3。

但它对 Stage 1 也有启发:

1
一开始设计 graph schema 时,就要考虑以后能不能学习、泛化和评估。

不要只做漂亮的知识图谱可视化。要让每条边、每个节点都能服务后续任务:

1
2
3
4
5
classification
recommendation
link prediction
failure diagnosis
next experiment planning

这就是 OpenGraph 对我们的长期价值。

下一步

HKUDS 图智能主线现在已经有:

1
2
HKUDS024 GraphAgent
HKUDS025 OpenGraph

下一步继续看:

1
2
HKUDS026 GraphGPT
HKUDS027 HiGPT

这四个项目合起来,会形成完整的 Graph / Knowledge Graph 学习组:

1
2
3
4
GraphAgent -> agentic graph-language execution
OpenGraph  -> graph foundation model / zero-shot graph learning
GraphGPT   -> graph instruction tuning / graph-language alignment
HiGPT      -> heterogeneous graph intelligence

这一组对我们后面做 QuantMind、factor graph、Research OS memory layer 都很关键。

This post is licensed under CC BY 4.0 by the author.