parsearena 0.1.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- parsearena/__init__.py +3 -0
- parsearena/cli.py +288 -0
- parsearena/demo/pdfs/NOTICE.md +36 -0
- parsearena/demo/pdfs/census-income-2023.pdf +0 -0
- parsearena/demo/pdfs/dpo-arxiv-2305.18290.pdf +0 -0
- parsearena/demo/pdfs/naca-report-1135-scan.pdf +0 -0
- parsearena/demo/questions.yaml +104 -0
- parsearena/demo/recorded.json +304 -0
- parsearena/errors.py +14 -0
- parsearena/evaluate.py +130 -0
- parsearena/llm.py +154 -0
- parsearena/parsers.py +197 -0
- parsearena/pipeline.py +276 -0
- parsearena/questions.py +125 -0
- parsearena/render.py +40 -0
- parsearena/report.py +57 -0
- parsearena/report_template.html +450 -0
- parsearena/retrieval.py +197 -0
- parsearena/runners/_common.py +148 -0
- parsearena/runners/run_docling.py +25 -0
- parsearena/runners/run_marker.py +54 -0
- parsearena/runners/run_mineru.py +59 -0
- parsearena/runners/run_pypdf.py +22 -0
- parsearena/runners/run_unstructured.py +38 -0
- parsearena/text.py +90 -0
- parsearena-0.1.3.dist-info/METADATA +267 -0
- parsearena-0.1.3.dist-info/RECORD +30 -0
- parsearena-0.1.3.dist-info/WHEEL +4 -0
- parsearena-0.1.3.dist-info/entry_points.txt +2 -0
- parsearena-0.1.3.dist-info/licenses/LICENSE +21 -0
parsearena/__init__.py
ADDED
parsearena/cli.py
ADDED
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
"""Command line interface."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import sys
|
|
7
|
+
import time
|
|
8
|
+
import webbrowser
|
|
9
|
+
from importlib import resources
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
import typer
|
|
13
|
+
from rich.console import Console
|
|
14
|
+
from rich.table import Table
|
|
15
|
+
|
|
16
|
+
from . import __version__
|
|
17
|
+
from .errors import UserError
|
|
18
|
+
from .evaluate import evaluate, timings
|
|
19
|
+
from .parsers import DEFAULT_PARSERS, PARSERS, env_dir, home, is_installed, missing_tools, parse_parser_list
|
|
20
|
+
from .pipeline import collect_docs, load_outputs, run_parser, save_outputs
|
|
21
|
+
from .questions import EXAMPLE, dump_questions, generate_questions, load_questions
|
|
22
|
+
from .retrieval import DEFAULT_EMBED_MODEL
|
|
23
|
+
|
|
24
|
+
app = typer.Typer(
|
|
25
|
+
add_completion=False,
|
|
26
|
+
no_args_is_help=True,
|
|
27
|
+
rich_markup_mode=None,
|
|
28
|
+
help="Run your PDFs through Docling, Marker, MinerU and Unstructured. "
|
|
29
|
+
"Compare the output side by side and see what each one does to retrieval.",
|
|
30
|
+
)
|
|
31
|
+
console = Console(highlight=False)
|
|
32
|
+
err = Console(stderr=True, highlight=False)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _version(value: bool) -> None:
|
|
36
|
+
if value:
|
|
37
|
+
console.print(f"parsearena {__version__}")
|
|
38
|
+
raise typer.Exit()
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@app.callback()
|
|
42
|
+
def _root(
|
|
43
|
+
version: bool = typer.Option(False, "--version", callback=_version, is_eager=True, help="Show version."),
|
|
44
|
+
) -> None:
|
|
45
|
+
pass
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _embedder(no_dense: bool, model: str):
|
|
49
|
+
if no_dense:
|
|
50
|
+
return None
|
|
51
|
+
try:
|
|
52
|
+
from .retrieval import FastEmbedder, model_is_cached
|
|
53
|
+
|
|
54
|
+
cache = str(home() / "models")
|
|
55
|
+
if model_is_cached(model, cache):
|
|
56
|
+
msg = f"Loading embedding model {model}..."
|
|
57
|
+
else:
|
|
58
|
+
size = ", about 65 MB" if model == DEFAULT_EMBED_MODEL else ""
|
|
59
|
+
msg = f"Downloading embedding model {model} (one time{size})..."
|
|
60
|
+
console.print(msg)
|
|
61
|
+
with console.status(msg):
|
|
62
|
+
return FastEmbedder(model, cache_dir=cache)
|
|
63
|
+
except Exception as exc: # network errors, unknown model names
|
|
64
|
+
raise UserError(
|
|
65
|
+
f"Could not load the embedding model {model}: {type(exc).__name__}: {exc}"[:400],
|
|
66
|
+
"Check your connection for the first download, pick another --embed-model, "
|
|
67
|
+
"or use --no-dense for BM25 only.",
|
|
68
|
+
) from exc
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _analyze(
|
|
72
|
+
recorded, pdf_paths, questions, out, k, no_dense, embed_model, chunk_chars, is_recorded, doc_info=None
|
|
73
|
+
):
|
|
74
|
+
from .report import build_report
|
|
75
|
+
|
|
76
|
+
outputs = load_outputs(recorded)
|
|
77
|
+
embedder = _embedder(no_dense, embed_model)
|
|
78
|
+
with console.status("Computing retrieval metrics..."):
|
|
79
|
+
ev = evaluate(outputs, questions, k=k, embedder=embedder, chunk_chars=chunk_chars)
|
|
80
|
+
ev["embed_model"] = embedder.name if embedder else None
|
|
81
|
+
ev["questions"] = len(questions)
|
|
82
|
+
tm = timings(outputs, {d["id"]: d["num_pages"] for d in recorded["docs"]})
|
|
83
|
+
with console.status("Rendering pages and writing the viewer..."):
|
|
84
|
+
index = build_report(out, recorded, pdf_paths, questions, ev, tm, is_recorded, doc_info)
|
|
85
|
+
_print_summary(recorded, ev, tm)
|
|
86
|
+
return index
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _pct(x: float) -> str:
|
|
90
|
+
# Round half up, like the viewer (Math.round), so terminal and HTML agree.
|
|
91
|
+
return f"{int(x * 100 + 0.5)}%"
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _print_summary(recorded, ev, tm) -> None:
|
|
95
|
+
labels = {p["name"]: p["label"] for p in recorded["parsers"]}
|
|
96
|
+
k = ev["k"]
|
|
97
|
+
table = Table(title=None, header_style="bold", pad_edge=False)
|
|
98
|
+
table.add_column("parser")
|
|
99
|
+
table.add_column("survives", justify="right")
|
|
100
|
+
for m in ev["methods"]:
|
|
101
|
+
table.add_column(f"R@{k} {m}", justify="right")
|
|
102
|
+
table.add_column("MRR " + ev["methods"][-1], justify="right")
|
|
103
|
+
table.add_column("s/page", justify="right")
|
|
104
|
+
table.add_column("failed", justify="right")
|
|
105
|
+
has_q = ev.get("questions", 0) > 0
|
|
106
|
+
for p, res in ev["parsers"].items():
|
|
107
|
+
s, t = res["summary"], tm[p]
|
|
108
|
+
spp = t["seconds_per_page"]
|
|
109
|
+
row = [labels.get(p, p), _pct(s["survives"]) if has_q else "-"]
|
|
110
|
+
row += [_pct(s[m]["recall"]) if has_q else "-" for m in ev["methods"]]
|
|
111
|
+
row += [f"{s[ev['methods'][-1]]['mrr']:.2f}" if has_q else "-"]
|
|
112
|
+
row += ["-" if spp is None else (f"{spp:.3f}" if spp < 0.1 else f"{spp:.1f}")]
|
|
113
|
+
row += [str(len(t["failed"])) if t["failed"] else "0"]
|
|
114
|
+
table.add_row(*row)
|
|
115
|
+
console.print(table)
|
|
116
|
+
if not has_q:
|
|
117
|
+
console.print(
|
|
118
|
+
"[yellow]No questions given, so retrieval metrics are empty.[/] "
|
|
119
|
+
"Pass --questions FILE or --gen-questions."
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def _open(index: Path, no_open: bool) -> None:
|
|
124
|
+
console.print(f"\nViewer: [bold]{index}[/]")
|
|
125
|
+
if not no_open:
|
|
126
|
+
webbrowser.open(index.resolve().as_uri())
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
@app.command()
|
|
130
|
+
def run(
|
|
131
|
+
pdfs: list[Path] = typer.Argument(..., help="PDF files to parse.", show_default=False),
|
|
132
|
+
parsers: str = typer.Option(
|
|
133
|
+
",".join(DEFAULT_PARSERS), "--parsers", "-p", help="Comma-separated parsers."
|
|
134
|
+
),
|
|
135
|
+
questions: Path | None = typer.Option(None, "--questions", "-q", help="YAML file with questions."),
|
|
136
|
+
gen_questions: bool = typer.Option(False, "--gen-questions", help="Draft questions with an LLM."),
|
|
137
|
+
per_doc: int = typer.Option(5, "--per-doc", help="Questions to draft per document."),
|
|
138
|
+
provider: str = typer.Option("ollama", "--provider", help="ollama, openrouter, openai or mistral."),
|
|
139
|
+
model: str = typer.Option("", "--model", help="Model for --gen-questions (default depends on provider)."),
|
|
140
|
+
max_cost: float = typer.Option(1.0, "--max-cost", help="Spending cap in USD for LLM calls."),
|
|
141
|
+
out: Path = typer.Option(Path("parsearena-out"), "--out", "-o", help="Output directory."),
|
|
142
|
+
k: int = typer.Option(5, "--k", help="k for recall@k."),
|
|
143
|
+
device: str = typer.Option("auto", "--device", help="auto, cpu, mps or cuda."),
|
|
144
|
+
timeout: int = typer.Option(3600, "--timeout", help="Seconds allowed per parser."),
|
|
145
|
+
chunk_chars: int = typer.Option(1200, "--chunk-chars", help="Maximum characters per chunk."),
|
|
146
|
+
embed_model: str = typer.Option(DEFAULT_EMBED_MODEL, "--embed-model", help="fastembed model name."),
|
|
147
|
+
no_dense: bool = typer.Option(False, "--no-dense", help="BM25 only, no embeddings."),
|
|
148
|
+
no_open: bool = typer.Option(False, "--no-open", help="Do not open the viewer."),
|
|
149
|
+
) -> None:
|
|
150
|
+
"""Parse PDFs with each parser in its own environment, then score retrieval."""
|
|
151
|
+
specs = parse_parser_list(parsers)
|
|
152
|
+
if device not in ("auto", "cpu", "mps", "cuda"):
|
|
153
|
+
raise UserError(f"Unknown device: {device}", "Use auto, cpu, mps or cuda.")
|
|
154
|
+
docs = collect_docs(pdfs)
|
|
155
|
+
out.mkdir(parents=True, exist_ok=True)
|
|
156
|
+
|
|
157
|
+
qs = []
|
|
158
|
+
if questions:
|
|
159
|
+
qs = load_questions(questions, docs)
|
|
160
|
+
elif gen_questions:
|
|
161
|
+
from .llm import LLM
|
|
162
|
+
from .render import page_text
|
|
163
|
+
|
|
164
|
+
llm = LLM(provider=provider, model=model, max_cost=max_cost)
|
|
165
|
+
console.print(f"Drafting questions with {provider}:{llm.model}")
|
|
166
|
+
texts = {d["id"]: "\n\n".join(page_text(Path(d["path"]))) for d in docs}
|
|
167
|
+
qs, _, budget_err = generate_questions(llm, docs, texts, per_doc=per_doc, log=console.print)
|
|
168
|
+
qpath = out / "questions.generated.yaml"
|
|
169
|
+
dump_questions(
|
|
170
|
+
qs, docs, qpath, header=f"# Drafted by {provider}:{llm.model}. Review before trusting."
|
|
171
|
+
)
|
|
172
|
+
console.print(f"Saved {len(qs)} questions to {qpath} (spent ${llm.spent:.4f})")
|
|
173
|
+
if budget_err:
|
|
174
|
+
raise budget_err
|
|
175
|
+
else:
|
|
176
|
+
console.print(
|
|
177
|
+
"[yellow]No --questions or --gen-questions: only the side-by-side viewer and timings.[/]"
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
outputs = {}
|
|
181
|
+
work = out / "work"
|
|
182
|
+
for spec in specs:
|
|
183
|
+
console.rule(f"{spec.label} {spec.version}")
|
|
184
|
+
for hint in missing_tools(spec):
|
|
185
|
+
console.print(f"[yellow]Warning:[/] {hint}")
|
|
186
|
+
if not is_installed(spec):
|
|
187
|
+
console.print(
|
|
188
|
+
f"First use of {spec.label}: installing it in its own environment. "
|
|
189
|
+
"This and the first parse can download several GB."
|
|
190
|
+
)
|
|
191
|
+
t0 = time.perf_counter()
|
|
192
|
+
with console.status(f"Running {spec.label} on {len(docs)} PDF(s)..."):
|
|
193
|
+
outputs[spec.name] = run_parser(
|
|
194
|
+
spec, docs, work, device=device, timeout=timeout, log=console.print
|
|
195
|
+
)
|
|
196
|
+
failed = [d for d, o in outputs[spec.name].items() if not o.ok]
|
|
197
|
+
status = f"[red]{len(failed)} failed[/]" if failed else "[green]ok[/]"
|
|
198
|
+
console.print(f"{spec.label}: {status} in {time.perf_counter() - t0:.0f}s (log: {work / spec.name})")
|
|
199
|
+
|
|
200
|
+
recorded = save_outputs(out / "outputs.json", docs, specs, outputs, device)
|
|
201
|
+
pdf_paths = {d["id"]: Path(d["path"]) for d in docs}
|
|
202
|
+
index = _analyze(recorded, pdf_paths, qs, out, k, no_dense, embed_model, chunk_chars, is_recorded=False)
|
|
203
|
+
_open(index, no_open)
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
@app.command()
|
|
207
|
+
def demo(
|
|
208
|
+
out: Path = typer.Option(Path("parsearena-demo"), "--out", "-o", help="Where to write the viewer."),
|
|
209
|
+
k: int = typer.Option(5, "--k", help="k for recall@k."),
|
|
210
|
+
no_dense: bool = typer.Option(False, "--no-dense", help="BM25 only, no embeddings download."),
|
|
211
|
+
no_open: bool = typer.Option(False, "--no-open", help="Do not open the viewer."),
|
|
212
|
+
) -> None:
|
|
213
|
+
"""Recorded parser outputs on 3 public PDFs; retrieval metrics computed live."""
|
|
214
|
+
base = Path(str(resources.files("parsearena") / "demo"))
|
|
215
|
+
recorded = json.loads((base / "recorded.json").read_text(encoding="utf-8"))
|
|
216
|
+
m = recorded["meta"]
|
|
217
|
+
created = m["created"].replace("T", " ").replace("Z", " UTC")
|
|
218
|
+
versions = ", ".join(f"{p['label']} {p['version']}" for p in recorded["parsers"])
|
|
219
|
+
console.print(
|
|
220
|
+
f"[bold]Recorded run[/] from {created} (parsearena {m['tool_version']}, {m['hardware']}).\n"
|
|
221
|
+
f"Parsers: {versions}.\nParser outputs are replayed; retrieval is computed now.\n"
|
|
222
|
+
)
|
|
223
|
+
docs = recorded["docs"]
|
|
224
|
+
qs = load_questions(base / "questions.yaml", docs)
|
|
225
|
+
pdf_paths = {d["id"]: base / "pdfs" / d["file"] for d in docs}
|
|
226
|
+
index = _analyze(
|
|
227
|
+
recorded,
|
|
228
|
+
pdf_paths,
|
|
229
|
+
qs,
|
|
230
|
+
out,
|
|
231
|
+
k,
|
|
232
|
+
no_dense,
|
|
233
|
+
DEFAULT_EMBED_MODEL,
|
|
234
|
+
recorded.get("chunk_chars", 1200),
|
|
235
|
+
is_recorded=True,
|
|
236
|
+
)
|
|
237
|
+
_open(index, no_open)
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
@app.command("parsers")
|
|
241
|
+
def list_parsers() -> None:
|
|
242
|
+
"""List supported parsers, pinned versions, licenses and install state."""
|
|
243
|
+
table = Table(header_style="bold")
|
|
244
|
+
for col in ("name", "package", "license", "installed"):
|
|
245
|
+
table.add_column(col)
|
|
246
|
+
for spec in PARSERS.values():
|
|
247
|
+
table.add_row(
|
|
248
|
+
spec.name,
|
|
249
|
+
" ".join(spec.packages),
|
|
250
|
+
spec.license,
|
|
251
|
+
str(env_dir(spec)) if is_installed(spec) else "no",
|
|
252
|
+
)
|
|
253
|
+
console.print(table)
|
|
254
|
+
console.print(f"Environments live in {home() / 'envs'} (set PARSEARENA_HOME to move them).")
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
@app.command("questions-example")
|
|
258
|
+
def questions_example() -> None:
|
|
259
|
+
"""Print an example questions YAML file."""
|
|
260
|
+
console.print(EXAMPLE, markup=False)
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
def main() -> None:
|
|
264
|
+
try:
|
|
265
|
+
app(standalone_mode=False)
|
|
266
|
+
except UserError as exc:
|
|
267
|
+
err.print(f"[bold red]Error:[/] {exc.message}", markup=True)
|
|
268
|
+
if exc.hint:
|
|
269
|
+
err.print(exc.hint, markup=False)
|
|
270
|
+
sys.exit(1)
|
|
271
|
+
except KeyboardInterrupt:
|
|
272
|
+
err.print("Interrupted.")
|
|
273
|
+
sys.exit(130)
|
|
274
|
+
except typer.Exit as exc:
|
|
275
|
+
sys.exit(exc.exit_code)
|
|
276
|
+
except typer.Abort:
|
|
277
|
+
sys.exit(1)
|
|
278
|
+
except Exception as exc:
|
|
279
|
+
import click
|
|
280
|
+
|
|
281
|
+
if isinstance(exc, click.ClickException):
|
|
282
|
+
exc.show()
|
|
283
|
+
sys.exit(exc.exit_code)
|
|
284
|
+
raise
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
if __name__ == "__main__":
|
|
288
|
+
main()
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Third-party documents
|
|
2
|
+
|
|
3
|
+
The PDFs in this directory are excerpts of third-party documents, bundled only as demo input.
|
|
4
|
+
They are not covered by parsearena's MIT license; each keeps its own terms, listed below.
|
|
5
|
+
|
|
6
|
+
## census-income-2023.pdf
|
|
7
|
+
|
|
8
|
+
- Title: Income in the United States: 2023 (Current Population Reports, P60-282), September 2024
|
|
9
|
+
- Authors: Gloria Guzman and Melissa Kollar, U.S. Census Bureau
|
|
10
|
+
- Source: https://www.census.gov/library/publications/2024/demo/p60-282.html
|
|
11
|
+
(PDF: https://www2.census.gov/library/publications/2024/demo/p60-282.pdf)
|
|
12
|
+
- License: public domain. Work of the U.S. federal government, not subject to copyright in the
|
|
13
|
+
United States (17 U.S.C. § 105).
|
|
14
|
+
- Changes: only report pages 1, 2 and 15 (PDF pages 7, 8 and 21) are included, unmodified.
|
|
15
|
+
|
|
16
|
+
## dpo-arxiv-2305.18290.pdf
|
|
17
|
+
|
|
18
|
+
- Title: Direct Preference Optimization: Your Language Model is Secretly a Reward Model (arXiv:2305.18290v3)
|
|
19
|
+
- Authors: Rafael Rafailov, Archit Sharma, Eric Mitchell, Stefano Ermon, Christopher D. Manning, Chelsea Finn
|
|
20
|
+
- Source: https://arxiv.org/abs/2305.18290
|
|
21
|
+
- License: Creative Commons Attribution 4.0 International (CC BY 4.0),
|
|
22
|
+
https://creativecommons.org/licenses/by/4.0/ , as declared on the arXiv abstract page.
|
|
23
|
+
- Attribution: "Direct Preference Optimization: Your Language Model is Secretly a Reward Model" by
|
|
24
|
+
Rafael Rafailov, Archit Sharma, Eric Mitchell, Stefano Ermon, Christopher D. Manning and Chelsea Finn,
|
|
25
|
+
arXiv:2305.18290v3, licensed under CC BY 4.0.
|
|
26
|
+
- Changes: only pages 1, 4, 5 and 9 are included; the pages themselves are unmodified.
|
|
27
|
+
|
|
28
|
+
## naca-report-1135-scan.pdf
|
|
29
|
+
|
|
30
|
+
- Title: Equations, Tables, and Charts for Compressible Flow (NACA Report 1135), 1953
|
|
31
|
+
- Authors: Ames Research Staff, Ames Aeronautical Laboratory, National Advisory Committee for Aeronautics
|
|
32
|
+
- Source: https://ntrs.nasa.gov/citations/19930091059
|
|
33
|
+
- License: public domain. Work of the U.S. federal government (17 U.S.C. § 105); NASA's Technical
|
|
34
|
+
Reports Server marks it "Public Use Permitted".
|
|
35
|
+
- Changes: only report page 613 (PDF page 2) is included, re-rendered at 200 dpi in grayscale as an
|
|
36
|
+
image-only page so that it has no text layer, like a scan.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Hand-written question set for the bundled demo PDFs.
|
|
2
|
+
# Each answer is a short string copied from the original page.
|
|
3
|
+
questions:
|
|
4
|
+
# U.S. Census Bureau, Income in the United States: 2023 (text page, chart page, table page)
|
|
5
|
+
- id: census-median
|
|
6
|
+
doc: census-income-2023.pdf
|
|
7
|
+
q: What was real median household income in the United States in 2023?
|
|
8
|
+
answers: ["80,610"]
|
|
9
|
+
- id: census-cpi
|
|
10
|
+
doc: census-income-2023.pdf
|
|
11
|
+
q: How much did consumer prices rise between 2022 and 2023 according to the C-CPI-U?
|
|
12
|
+
answers: ["4.0 percent increase"]
|
|
13
|
+
- id: census-earnings-ratio
|
|
14
|
+
doc: census-income-2023.pdf
|
|
15
|
+
q: What was the female-to-male earnings ratio for full-time, year-round workers in 2023?
|
|
16
|
+
answers: ["82.7 percent"]
|
|
17
|
+
- id: census-survey
|
|
18
|
+
doc: census-income-2023.pdf
|
|
19
|
+
q: Which survey supplement are the income estimates based on?
|
|
20
|
+
answers: ["Annual Social and Economic Supplements"]
|
|
21
|
+
- id: census-asian
|
|
22
|
+
doc: census-income-2023.pdf
|
|
23
|
+
q: What was the median income of Asian households in 2023?
|
|
24
|
+
answers: ["112,800"]
|
|
25
|
+
- id: census-bachelor
|
|
26
|
+
doc: census-income-2023.pdf
|
|
27
|
+
q: What was the median household income for householders with a bachelor's degree or higher in 2023?
|
|
28
|
+
answers: ["126,800"]
|
|
29
|
+
- id: census-midwest
|
|
30
|
+
doc: census-income-2023.pdf
|
|
31
|
+
q: What was the median household income in the Midwest in 2023?
|
|
32
|
+
answers: ["81,020"]
|
|
33
|
+
- id: census-nonmetro
|
|
34
|
+
doc: census-income-2023.pdf
|
|
35
|
+
q: What was the median income of households outside metropolitan statistical areas in 2023?
|
|
36
|
+
answers: ["62,520"]
|
|
37
|
+
- id: census-households
|
|
38
|
+
doc: census-income-2023.pdf
|
|
39
|
+
q: How many households (in thousands) were there in 2023?
|
|
40
|
+
answers: ["132,200"]
|
|
41
|
+
- id: census-foreign
|
|
42
|
+
doc: census-income-2023.pdf
|
|
43
|
+
q: What was the 2023 median income of households with a foreign-born householder?
|
|
44
|
+
answers: ["73,360"]
|
|
45
|
+
|
|
46
|
+
# Rafailov et al., Direct Preference Optimization (arXiv:2305.18290, CC BY 4.0)
|
|
47
|
+
- id: dpo-name
|
|
48
|
+
doc: dpo-arxiv-2305.18290.pdf
|
|
49
|
+
q: What does the acronym DPO stand for?
|
|
50
|
+
answers: ["Direct Preference Optimization"]
|
|
51
|
+
- id: dpo-preference-model
|
|
52
|
+
doc: dpo-arxiv-2305.18290.pdf
|
|
53
|
+
q: Under which preference model does the partition function cancel out in the DPO derivation?
|
|
54
|
+
answers: ["Bradley-Terry"]
|
|
55
|
+
- id: dpo-z
|
|
56
|
+
doc: dpo-arxiv-2305.18290.pdf
|
|
57
|
+
q: What is Z(x) called in the closed-form optimal policy?
|
|
58
|
+
answers: ["partition function"]
|
|
59
|
+
- id: dpo-gradient-weight
|
|
60
|
+
doc: dpo-arxiv-2305.18290.pdf
|
|
61
|
+
q: In the gradient of the DPO loss, when does an example get a higher weight?
|
|
62
|
+
answers: ["when reward estimate is wrong"]
|
|
63
|
+
- id: dpo-tldr
|
|
64
|
+
doc: dpo-arxiv-2305.18290.pdf
|
|
65
|
+
q: What win rate does DPO reach on TL;DR summarization at temperature 0.0?
|
|
66
|
+
answers: ["61%"]
|
|
67
|
+
- id: dpo-cnn
|
|
68
|
+
doc: dpo-arxiv-2305.18290.pdf
|
|
69
|
+
q: What GPT-4 win rate against ground truth does DPO get on CNN/DailyMail at temperature 0?
|
|
70
|
+
answers: ["0.36"]
|
|
71
|
+
- id: dpo-dialogue-model
|
|
72
|
+
doc: dpo-arxiv-2305.18290.pdf
|
|
73
|
+
q: Which pre-trained model is the starting point for the single-turn dialogue experiments?
|
|
74
|
+
answers: ["Pythia-2.8B"]
|
|
75
|
+
- id: dpo-venue
|
|
76
|
+
doc: dpo-arxiv-2305.18290.pdf
|
|
77
|
+
q: At which conference was the DPO paper published?
|
|
78
|
+
answers: ["NeurIPS 2023"]
|
|
79
|
+
|
|
80
|
+
# NACA Report 1135 (1953), a scanned page with no text layer (public domain)
|
|
81
|
+
- id: naca-report
|
|
82
|
+
doc: naca-report-1135-scan.pdf
|
|
83
|
+
q: What is the report number of "Equations, Tables, and Charts for Compressible Flow"?
|
|
84
|
+
answers: ["Report 1135"]
|
|
85
|
+
- id: naca-tn
|
|
86
|
+
doc: naca-report-1135-scan.pdf
|
|
87
|
+
q: Which NACA technical note does the compressible flow report revise and extend?
|
|
88
|
+
answers: ["1428"]
|
|
89
|
+
- id: naca-authors
|
|
90
|
+
doc: naca-report-1135-scan.pdf
|
|
91
|
+
q: Who is credited as the author of the compressible flow report?
|
|
92
|
+
answers: ["Ames Research Staff"]
|
|
93
|
+
- id: naca-gamma
|
|
94
|
+
doc: naca-report-1135-scan.pdf
|
|
95
|
+
q: What quantity does the symbol gamma stand for in the compressible flow notation?
|
|
96
|
+
answers: ["ratio of specific heats"]
|
|
97
|
+
- id: naca-extensions
|
|
98
|
+
doc: naca-report-1135-scan.pdf
|
|
99
|
+
q: In which direction were the compressible flow tables extended, according to the introduction?
|
|
100
|
+
answers: ["higher Mach numbers"]
|
|
101
|
+
- id: naca-vm
|
|
102
|
+
doc: naca-report-1135-scan.pdf
|
|
103
|
+
q: What does V_m denote in the list of symbols?
|
|
104
|
+
answers: ["maximum speed obtainable"]
|