orbitsight / scripts /render_longform_proposal.py
HishaamA's picture
Update long-form proposal renderer for architecture diagram
a6f073a verified
Raw
History Blame Contribute Delete
17.4 kB
#!/usr/bin/env python3
"""Render the long-form OrbitSight review proposal and its supporting charts."""
from __future__ import annotations
import re
import textwrap
from pathlib import Path
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
ROOT = Path(__file__).resolve().parents[1]
SOURCE = ROOT / "docs" / "OrbitSight_Full_Technical_Proposal_Review.md"
OUTPUT = ROOT / "docs" / "OrbitSight_Full_Technical_Proposal_Review.pdf"
ASSETS = ROOT / "docs" / "full_proposal_assets"
NAVY = "#15253b"
BLUE = "#2274a5"
CYAN = "#42b3c7"
RED = "#b33a3a"
GREY = "#5f6b76"
LIGHT = "#eef3f6"
def make_model_evolution() -> None:
stages = [
"First honest\nbaseline",
"Early\ntraining",
"V5 + gates",
"V7",
"Heavy\nhybrid",
"Initial\nstudent",
"Final\nstudent",
]
f1 = [0.0364, 0.5150, 0.6298, 0.5954, 0.6683, 0.6229, 0.6292]
map_scores = [0.0096, 0.2200, 0.3804, 0.3585, 0.4895, 0.4608, 0.4645]
x = range(len(stages))
fig, ax = plt.subplots(figsize=(11.2, 5.4))
fig.patch.set_facecolor("white")
ax.plot(x, f1, marker="o", linewidth=2.5, color=BLUE, label="Leakage-free F1")
ax.plot(x, map_scores, marker="o", linewidth=2.5, color=CYAN, label="Leakage-free mAP")
for index, value in enumerate(f1):
ax.text(index, value + 0.022, f"{value:.3f}", ha="center", fontsize=8, color=NAVY)
for index, value in enumerate(map_scores):
ax.text(index, value - 0.045, f"{value:.3f}", ha="center", fontsize=8, color=GREY)
ax.set_xticks(list(x), stages)
ax.set_ylim(0, 0.76)
ax.set_ylabel("Score")
ax.set_title("OrbitSight development: accuracy improved, then latency became the constraint", loc="left", fontweight="bold", color=NAVY)
ax.grid(axis="y", alpha=0.22)
ax.spines[["top", "right"]].set_visible(False)
ax.legend(frameon=False, ncol=2, loc="upper left")
ax.text(
0,
-0.27,
"Early-training 0.515/0.220 is a historical validation checkpoint and is not strictly comparable to the later locked evaluations.",
transform=ax.transAxes,
fontsize=8,
color=GREY,
)
fig.subplots_adjust(left=0.08, right=0.98, top=0.86, bottom=0.27)
fig.savefig(ASSETS / "model_evolution.png", dpi=180, bbox_inches="tight")
plt.close(fig)
def make_heavy_vs_student() -> None:
labels = ["Heavy V5/V7 hybrid", "Distilled CPU student"]
params = [8_588_339, 135_111]
latency = [383.0, 17.05]
fig, axes = plt.subplots(1, 2, figsize=(11.2, 4.8))
fig.patch.set_facecolor("white")
colors = [RED, BLUE]
axes[0].barh(labels, params, color=colors)
axes[0].set_xscale("log")
axes[0].set_title("Parameters (log scale)", loc="left", fontweight="bold", color=NAVY)
axes[0].set_xlabel("Parameters")
for idx, value in enumerate(params):
axes[0].text(value * 1.08, idx, f"{value:,}", va="center", fontsize=9)
axes[1].barh(labels, latency, color=colors)
axes[1].axvline(40, color=NAVY, linestyle="--", linewidth=1.5, label="40 ms requirement")
axes[1].set_title("Measured CPU latency", loc="left", fontweight="bold", color=NAVY)
axes[1].set_xlabel("Mean milliseconds per window")
axes[1].legend(frameon=False, fontsize=8)
for idx, value in enumerate(latency):
axes[1].text(value + 6, idx, f"{value:.2f} ms", va="center", fontsize=9)
for ax in axes:
ax.grid(axis="x", alpha=0.2)
ax.spines[["top", "right"]].set_visible(False)
fig.suptitle("Distillation made the deployment constraint achievable", x=0.06, ha="left", fontweight="bold", color=NAVY, fontsize=14)
fig.subplots_adjust(left=0.20, right=0.97, bottom=0.16, top=0.78, wspace=0.38)
fig.savefig(ASSETS / "heavy_vs_student.png", dpi=180, bbox_inches="tight")
plt.close(fig)
def make_final_student_architecture() -> None:
"""Draw the exact deployed tensor path, including recurrent state and inactive heads."""
fig, ax = plt.subplots(figsize=(15.5, 8.6))
fig.patch.set_facecolor("white")
ax.set_xlim(0, 15.5)
ax.set_ylim(0, 8.6)
ax.axis("off")
def box(x, y, w, h, title, body, color=BLUE, dashed=False):
patch = plt.Rectangle(
(x, y), w, h, facecolor="white", edgecolor=color, linewidth=1.8,
linestyle="--" if dashed else "-", joinstyle="round"
)
ax.add_patch(patch)
ax.text(x + 0.12, y + h - 0.18, title, va="top", fontsize=10,
fontweight="bold", color=color)
ax.text(x + 0.12, y + h - 0.55, body, va="top", fontsize=8.1,
color=NAVY, linespacing=1.28)
def arrow(x1, y1, x2, y2, color=NAVY, style="-"):
ax.annotate("", xy=(x2, y2), xytext=(x1, y1),
arrowprops=dict(arrowstyle="->", color=color, lw=1.4,
linestyle=style, shrinkA=2, shrinkB=2))
ax.text(0.35, 8.25, "Final OrbitSight CPU student — exact deployed architecture",
fontsize=17, fontweight="bold", color=NAVY)
ax.text(0.35, 7.88, "Solid boxes execute at inference; dashed boxes are stored/training-only.",
fontsize=9, color=GREY)
box(0.35, 5.25, 1.65, 1.35, "40 ms input", "3×640×640\npositive count\nnegative count\nrecency", CYAN)
box(2.35, 5.25, 1.65, 1.35, "Stem · 120 p", "3×3 Conv 3→4\nBatchNorm + SiLU\n4×640×640")
arrow(2.0, 5.93, 2.35, 5.93)
stages = [
(4.35, "Stage 1", "down 4→4 · s2\nConvLSTM d1\n4×320×320\n1,324 p"),
(6.35, "Stage 2", "down 4→8 · s2\nConvLSTM d2\n8×160×160\n4,952 p"),
(8.35, "Stage 3", "down 8→16 · s2\nConvLSTM d4\n16×80×80\n19,696 p"),
(10.35, "Stage 4", "down 16→32 · s2\nConvLSTM d8\n32×40×40\n78,560 p"),
]
for x, title, body in stages:
box(x, 5.05, 1.65, 1.75, title, body)
for start in [4.0, 6.0, 8.0, 10.0]:
arrow(start, 5.93, start + 0.35, 5.93)
for x, label in [(5.0, "H,C\nstate"), (7.0, "H,C\nstate"),
(9.0, "H,C\nstate"), (11.0, "H,C\nstate")]:
ax.annotate(label, xy=(x + 0.17, 6.75), xytext=(x + 0.17, 7.52),
ha="center", va="center", fontsize=7.5, color=RED,
arrowprops=dict(arrowstyle="<->", color=RED, lw=1.1))
heads = [
(6.25, 2.55, "Stride-4 head", "8→16→16\nreg 4×160²\nobj 1×160²\n3,573 active p"),
(8.25, 2.55, "Stride-8 head", "16→16→16\nreg 4×80²\nobj 1×80²\n4,725 active p"),
(10.25, 2.55, "Stride-16 head", "32→16→16\nreg 4×40²\nobj 1×40²\n7,029 active p"),
]
for x, y, title, body in heads:
box(x, y, 1.75, 1.65, title, body, CYAN)
arrow(7.15, 5.05, 7.15, 4.2)
arrow(9.15, 5.05, 9.15, 4.2)
arrow(11.15, 5.05, 11.15, 4.2)
box(12.45, 2.55, 2.45, 1.65, "Exact top-one decoder",
"33,600 scores → stable argmax\nthreshold 0.10\ndecode only winning cell\nno production NMS", RED)
for x in [8.0, 10.0, 12.0]:
arrow(x, 3.37, 12.45, 3.37)
box(12.45, 5.05, 2.45, 1.75, "Native output path",
"inverse area mapping\nDVX size ×0.98\nKalman/coast tracker\nsensor gate → integer row", BLUE)
arrow(13.68, 4.2, 13.68, 5.05)
box(0.35, 0.55, 3.45, 1.25, "Selective training objective",
"human focal + pixel-inclusive CIoU + aux BCE\n+ matched-teacher confidence/box + empty-window negatives", GREY, dashed=True)
box(4.15, 0.55, 3.45, 1.25, "Auxiliary segmentation · 9 p",
"1×1 Conv on stride-4 feature → 1×160×160\nexecuted only while model.training", GREY, dashed=True)
box(7.95, 0.55, 3.45, 1.25, "Compatibility classification · 15,123 p",
"three stored cls towers/predictors\ncompute_cls=False; never scored", GREY, dashed=True)
box(11.75, 0.55, 3.15, 1.25, "Checkpoint contract",
"135,111 stored parameters\nquality head: off · sensor FiLM: off", GREY, dashed=True)
fig.subplots_adjust(left=0.015, right=0.985, top=0.98, bottom=0.03)
fig.savefig(ASSETS / "final_student_architecture.png", dpi=180, bbox_inches="tight")
plt.close(fig)
def clean_inline(value: str) -> str:
value = re.sub(r"!\[[^]]*]\([^)]+\)", "", value)
value = re.sub(r"\[([^]]+)]\([^)]+\)", r"\1", value)
return value.replace("**", "").replace("__", "").replace("`", "")
class Renderer:
width = 8.27
height = 11.69
left = 0.085
right = 0.925
top = 0.925
bottom = 0.075
def __init__(self, pdf: PdfPages) -> None:
self.pdf = pdf
self.fig = None
self.ax = None
self.y = self.top
self.page = 0
self.new_page()
def new_page(self) -> None:
if self.fig is not None:
self.finish_page()
self.page += 1
self.fig = plt.figure(figsize=(self.width, self.height), facecolor="white")
self.ax = self.fig.add_axes([0, 0, 1, 1])
self.ax.axis("off")
self.y = self.top
def finish_page(self) -> None:
self.fig.text(self.left, 0.035, "OrbitSight — Full Technical Proposal Review", fontsize=7, color=GREY)
self.fig.text(self.right, 0.035, str(self.page), fontsize=7, color=GREY, ha="right")
self.pdf.savefig(self.fig, bbox_inches=None)
plt.close(self.fig)
def ensure(self, needed: float) -> None:
if self.y - needed < self.bottom:
self.new_page()
def rule(self, color: str = CYAN) -> None:
self.ensure(0.025)
self.ax.plot([self.left, self.right], [self.y, self.y], transform=self.fig.transFigure, color=color, linewidth=1.2)
self.y -= 0.025
def text(self, value: str, *, size: float = 9.2, color: str = NAVY, bold: bool = False,
indent: float = 0.0, before: float = 0.006, after: float = 0.008,
mono: bool = False, prefix: str = "") -> None:
value = clean_inline(value).strip()
if not value:
self.y -= after
return
chars = max(28, int((104 - indent * 95) * 9.2 / size))
subsequent = " " * len(prefix)
lines = textwrap.wrap(prefix + value, width=chars, subsequent_indent=subsequent,
break_long_words=False, break_on_hyphens=False) or [value]
line_h = size / 850
needed = before + len(lines) * line_h + after
self.ensure(needed)
self.y -= before
for line in lines:
self.fig.text(self.left + indent, self.y, line, fontsize=size, color=color,
fontweight="bold" if bold else "normal",
family="DejaVu Sans Mono" if mono else "DejaVu Sans",
va="top")
self.y -= line_h
self.y -= after
def heading(self, value: str, level: int) -> None:
if level == 1:
self.ensure(0.14)
self.text(value, size=21, bold=True, before=0.015, after=0.012)
self.rule()
elif level == 2:
self.ensure(0.085)
self.text(value, size=14.2, color=BLUE, bold=True, before=0.025, after=0.008)
else:
self.ensure(0.06)
self.text(value, size=11.2, bold=True, before=0.018, after=0.006)
def code(self, lines: list[str]) -> None:
rendered: list[str] = []
for line in lines:
rendered.extend(textwrap.wrap(line, width=96, subsequent_indent=" ", replace_whitespace=False) or [""])
line_h = 8.0 / 850
needed = len(rendered) * line_h + 0.028
self.ensure(needed)
y_top = self.y - 0.006
y_bottom = y_top - len(rendered) * line_h - 0.012
self.ax.add_patch(plt.Rectangle((self.left - 0.008, y_bottom), self.right - self.left + 0.016,
y_top - y_bottom, transform=self.fig.transFigure,
facecolor=LIGHT, edgecolor="#d8e1e7", linewidth=0.6))
self.y = y_top - 0.008
for line in rendered:
self.fig.text(self.left, self.y, line, fontsize=8, color=NAVY, family="DejaVu Sans Mono", va="top")
self.y -= line_h
self.y = y_bottom - 0.012
def table(self, lines: list[str]) -> None:
rows = []
for line in lines:
cells = [clean_inline(cell.strip()) for cell in line.strip().strip("|").split("|")]
if all(re.fullmatch(r":?-{3,}:?", cell) for cell in cells):
continue
rows.append(cells)
if not rows:
return
cols = max(len(row) for row in rows)
normalized = [row + [""] * (cols - len(row)) for row in rows]
max_width = 98
cell_width = max(10, max_width // cols - 2)
formatted = []
for row_index, row in enumerate(normalized):
wrapped = [textwrap.wrap(cell, width=cell_width, break_long_words=False) or [""] for cell in row]
row_height = max(len(cell) for cell in wrapped)
for line_index in range(row_height):
values = []
for cell in wrapped:
value = cell[line_index] if line_index < len(cell) else ""
values.append(value.ljust(cell_width))
formatted.append(" ".join(values).rstrip())
if row_index == 0:
formatted.append(" ".join("─" * cell_width for _ in range(cols)))
self.code(formatted)
def image(self, relative: str, alt: str) -> None:
path = (SOURCE.parent / relative).resolve()
if not path.exists():
self.text(f"[Image unavailable: {alt}]", color=RED)
return
data = plt.imread(path)
ratio = data.shape[0] / data.shape[1]
box_width = self.right - self.left
box_height = min(0.39, box_width * ratio * self.width / self.height)
self.ensure(box_height + 0.05)
image_ax = self.fig.add_axes([self.left, self.y - box_height, box_width, box_height])
image_ax.imshow(data)
image_ax.axis("off")
self.y -= box_height + 0.006
self.text(alt, size=7.5, color=GREY, before=0.0, after=0.014)
def close(self) -> None:
if self.fig is not None:
self.finish_page()
self.fig = None
def render_markdown() -> None:
lines = SOURCE.read_text(encoding="utf-8").splitlines()
with PdfPages(OUTPUT) as pdf:
metadata = pdf.infodict()
metadata["Title"] = "OrbitSight Full Technical Proposal Review"
metadata["Author"] = "Team Simer"
metadata["Subject"] = "Development history, architecture, evaluation, latency and deployment"
renderer = Renderer(pdf)
index = 0
in_code = False
code_lines: list[str] = []
while index < len(lines):
line = lines[index]
if line.startswith("```"):
if in_code:
renderer.code(code_lines)
code_lines = []
in_code = False
else:
in_code = True
index += 1
continue
if in_code:
code_lines.append(line)
index += 1
continue
image_match = re.fullmatch(r"!\[([^]]*)]\(([^)]+)\)", line.strip())
if image_match:
renderer.image(image_match.group(2), image_match.group(1))
index += 1
continue
if line.startswith("|"):
table_lines = []
while index < len(lines) and lines[index].startswith("|"):
table_lines.append(lines[index])
index += 1
renderer.table(table_lines)
continue
heading_match = re.match(r"^(#{1,3})\s+(.+)$", line)
if heading_match:
renderer.heading(heading_match.group(2), len(heading_match.group(1)))
elif re.match(r"^[-*]\s+", line):
renderer.text(re.sub(r"^[-*]\s+", "", line), indent=0.018, prefix="• ")
elif re.match(r"^\d+\.\s+", line):
match = re.match(r"^(\d+\.)\s+(.+)$", line)
renderer.text(match.group(2), indent=0.018, prefix=f"{match.group(1)} ")
elif line.startswith(">"):
renderer.text(line.lstrip("> "), color=RED, indent=0.018, bold=True)
elif line.strip() in {"---", "***"}:
renderer.rule(color="#c8d2da")
elif line.strip():
paragraph = [line.strip()]
while index + 1 < len(lines):
nxt = lines[index + 1]
if not nxt.strip() or nxt.startswith(("#", "|", "```", ">", "![")) or re.match(r"^[-*]\s+|^\d+\.\s+", nxt):
break
paragraph.append(nxt.strip())
index += 1
renderer.text(" ".join(paragraph))
else:
renderer.y -= 0.006
index += 1
if code_lines:
renderer.code(code_lines)
renderer.close()
def main() -> None:
ASSETS.mkdir(parents=True, exist_ok=True)
make_model_evolution()
make_heavy_vs_student()
make_final_student_architecture()
render_markdown()
print(f"Rendered {OUTPUT}")
if __name__ == "__main__":
main()