-
Notifications
You must be signed in to change notification settings - Fork 354
Expand file tree
/
Copy pathpaper.py
More file actions
154 lines (140 loc) · 4.5 KB
/
Copy pathpaper.py
File metadata and controls
154 lines (140 loc) · 4.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
"""Build, persist, reopen, and search the Transformer paper artifacts."""
import asyncio
import os
from collections.abc import Sequence
from pathlib import Path
from dotenv import load_dotenv
from quantmind.configs import PaperFlowCfg
from quantmind.configs.paper import ArxivIdentifier
from quantmind.flows import paper_flow
from quantmind.knowledge import (
PaperArtifactKind,
PaperChunk,
PaperGlobalSummary,
)
from quantmind.library import (
LocalKnowledgeLibrary,
SemanticHit,
SemanticQuery,
)
_ARXIV_ID = "1706.03762v7"
_EMBEDDING_MODEL = "text-embedding-3-small"
async def _search_and_resolve(
library: LocalKnowledgeLibrary,
) -> tuple[
list[SemanticHit],
list[SemanticHit],
Sequence[object],
]:
"""Run both V1 retrieval grains and resolve every returned locator."""
summary_hits = await library.search(
SemanticQuery(
text="What is the paper's central contribution?",
artifact_kinds=[PaperArtifactKind.GLOBAL_SUMMARY],
top_k=3,
)
)
chunk_hits = await library.search(
SemanticQuery(
text="How does multi-head attention work?",
artifact_kinds=[PaperArtifactKind.CHUNK_SET],
top_k=5,
)
)
resolved = [
await library.resolve(hit.locator)
for hit in (*summary_hits, *chunk_hits)
]
return summary_hits, chunk_hits, resolved
async def main() -> None:
"""Run the common Paper Flow V1 path and print auditable evidence."""
load_dotenv()
if not os.getenv("OPENAI_API_KEY"):
raise SystemExit("Set OPENAI_API_KEY before running this example.")
workspace = Path(".quantmind")
workspace.mkdir(exist_ok=True)
result = await paper_flow(
ArxivIdentifier(id=_ARXIV_ID),
cfg=PaperFlowCfg(
model="gpt-4o-mini",
output_dir=str(workspace / "attention-assets"),
),
)
database = workspace / "library.db"
library = await LocalKnowledgeLibrary.open(
database,
embedding_model=_EMBEDDING_MODEL,
)
try:
await library.put_paper(result)
(
first_summary_hits,
first_chunk_hits,
first_resolved,
) = await _search_and_resolve(library)
finally:
await library.close()
library = await LocalKnowledgeLibrary.open(
database,
embedding_model=_EMBEDDING_MODEL,
)
try:
restored = await library.get_paper(
result.source_revision.id,
chunk_set_id=result.chunk_set.id,
summary_id=result.global_summary.id,
)
(
second_summary_hits,
second_chunk_hits,
second_resolved,
) = await _search_and_resolve(library)
print(restored.global_summary.summary)
print(
"summary_orchestration="
f"{restored.global_summary.producer.orchestration}"
)
print(
f"chunks={len(restored.chunk_set.chunks)} "
f"source_pages={len(restored.source_revision.parsed.pages)}"
)
print(
"citations="
+ ", ".join(
f"page {citation.page_number} / chunk {citation.chunk_id}"
for citation in restored.global_summary.citations
)
)
print(
"scores_before_reopen="
f"summary={[hit.score for hit in first_summary_hits]} "
f"chunks={[hit.score for hit in first_chunk_hits]}"
)
print(
"scores_after_reopen="
f"summary={[hit.score for hit in second_summary_hits]} "
f"chunks={[hit.score for hit in second_chunk_hits]}"
)
for hit, resolved in zip(
(*second_summary_hits, *second_chunk_hits),
second_resolved,
strict=True,
):
if isinstance(resolved, PaperGlobalSummary):
detail = "global summary"
elif isinstance(resolved, PaperChunk):
pages = sorted(
{span.page_number for span in resolved.source_spans}
)
detail = f"chunk pages={pages} text={resolved.text[:120]!r}"
else:
detail = type(resolved).__name__
print(f"score={hit.score:.3f} {detail}")
print(
f"resolved_before_reopen={len(first_resolved)} "
f"resolved_after_reopen={len(second_resolved)}"
)
finally:
await library.close()
if __name__ == "__main__":
asyncio.run(main())