Upload app.py with huggingface_hub
Browse files
app.py
CHANGED
|
@@ -59,25 +59,41 @@ def _counter(text: str) -> str:
|
|
| 59 |
)
|
| 60 |
|
| 61 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
def _estimate_duration(text, num_candidates=3, structured_fallback=True, *args, **kwargs):
|
| 63 |
if structured_fallback and infer_kind((text or "").strip()) in ("html", "data"):
|
| 64 |
return 10
|
| 65 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 66 |
|
| 67 |
|
| 68 |
-
def _run_harness(text: str, num_candidates: int, structured_fallback: bool) -> dict:
|
|
|
|
|
|
|
|
|
|
| 69 |
started = time.perf_counter()
|
| 70 |
result = convert_to_markdown(
|
| 71 |
model,
|
| 72 |
tokenizer,
|
| 73 |
text,
|
| 74 |
-
num_candidates=
|
| 75 |
do_sample=True,
|
| 76 |
temperature=0.3,
|
| 77 |
top_p=0.95,
|
| 78 |
seed=0,
|
| 79 |
use_cache=True,
|
| 80 |
-
structured_fallback=
|
| 81 |
skip_model_for_structured=True,
|
| 82 |
)
|
| 83 |
result["elapsed"] = time.perf_counter() - started
|
|
@@ -85,7 +101,7 @@ def _run_harness(text: str, num_candidates: int, structured_fallback: bool) -> d
|
|
| 85 |
|
| 86 |
|
| 87 |
@spaces.GPU(duration=_estimate_duration)
|
| 88 |
-
def convert(text: str, num_candidates: int =
|
| 89 |
"""Convert a plain-text document into faithful GitHub-Flavored Markdown.
|
| 90 |
|
| 91 |
PASITA samples the document several times, every candidate is post-processed and
|
|
@@ -129,7 +145,7 @@ def convert(text: str, num_candidates: int = 3, structured_fallback: bool = True
|
|
| 129 |
|
| 130 |
|
| 131 |
@spaces.GPU(duration=_estimate_duration)
|
| 132 |
-
def gpu_convert(text: str, num_candidates: int =
|
| 133 |
"""Convert a document and return the full conversion result.
|
| 134 |
|
| 135 |
Same pipeline as the UI conversion. Used by the /v1 OpenAI-style API routes.
|
|
@@ -623,6 +639,14 @@ footer[aria-label="Gradio footer navigation"] { display: none !important; }
|
|
| 623 |
#p-settings { background: transparent !important; border: 1px solid var(--hair-soft) !important; border-radius: 12px !important; margin-top: 4px; }
|
| 624 |
#p-settings > .label-wrap { font-family: var(--font-mono) !important; font-size: 0.68rem !important; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted) !important; }
|
| 625 |
#p-settings > .label-wrap .icon { color: var(--muted-2) !important; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 626 |
#p-settings .p-label { margin-bottom: 4px; }
|
| 627 |
|
| 628 |
.p-foot {
|
|
@@ -672,10 +696,13 @@ with gr.Blocks(title="PASITA: plain text to Markdown") as demo:
|
|
| 672 |
elem_id="p-text",
|
| 673 |
)
|
| 674 |
with gr.Accordion("SETTINGS", open=False, elem_id="p-settings"):
|
| 675 |
-
candidates = gr.
|
| 676 |
-
|
|
|
|
|
|
|
| 677 |
label="PASITA CANDIDATES",
|
| 678 |
info="More samples improve the reranker. 3 is the measured default.",
|
|
|
|
| 679 |
)
|
| 680 |
structured = gr.Checkbox(
|
| 681 |
value=True,
|
|
|
|
| 59 |
)
|
| 60 |
|
| 61 |
|
| 62 |
+
def _normalize(text: str | None, num_candidates: int | None, structured_fallback: bool | None) -> tuple[str, int, bool]:
|
| 63 |
+
text = (text or "").strip()
|
| 64 |
+
if num_candidates is None:
|
| 65 |
+
num_candidates = 3
|
| 66 |
+
if structured_fallback is None:
|
| 67 |
+
structured_fallback = True
|
| 68 |
+
return text, max(1, min(3, int(num_candidates))), bool(structured_fallback)
|
| 69 |
+
|
| 70 |
+
|
| 71 |
def _estimate_duration(text, num_candidates=3, structured_fallback=True, *args, **kwargs):
|
| 72 |
if structured_fallback and infer_kind((text or "").strip()) in ("html", "data"):
|
| 73 |
return 10
|
| 74 |
+
try:
|
| 75 |
+
candidates = int(num_candidates)
|
| 76 |
+
except (TypeError, ValueError):
|
| 77 |
+
candidates = 3
|
| 78 |
+
return min(30, max(12, 8 + len(text or "") // 200 + 4 * (candidates - 1)))
|
| 79 |
|
| 80 |
|
| 81 |
+
def _run_harness(text: str | None, num_candidates: int | None, structured_fallback: bool | None) -> dict:
|
| 82 |
+
text, num_candidates, structured_fallback = _normalize(text, num_candidates, structured_fallback)
|
| 83 |
+
if not text:
|
| 84 |
+
raise ValueError("Paste a document to convert.")
|
| 85 |
started = time.perf_counter()
|
| 86 |
result = convert_to_markdown(
|
| 87 |
model,
|
| 88 |
tokenizer,
|
| 89 |
text,
|
| 90 |
+
num_candidates=num_candidates,
|
| 91 |
do_sample=True,
|
| 92 |
temperature=0.3,
|
| 93 |
top_p=0.95,
|
| 94 |
seed=0,
|
| 95 |
use_cache=True,
|
| 96 |
+
structured_fallback=structured_fallback,
|
| 97 |
skip_model_for_structured=True,
|
| 98 |
)
|
| 99 |
result["elapsed"] = time.perf_counter() - started
|
|
|
|
| 101 |
|
| 102 |
|
| 103 |
@spaces.GPU(duration=_estimate_duration)
|
| 104 |
+
def convert(text: str | None = None, num_candidates: int | None = None, structured_fallback: bool | None = None) -> tuple[str, str, str]:
|
| 105 |
"""Convert a plain-text document into faithful GitHub-Flavored Markdown.
|
| 106 |
|
| 107 |
PASITA samples the document several times, every candidate is post-processed and
|
|
|
|
| 145 |
|
| 146 |
|
| 147 |
@spaces.GPU(duration=_estimate_duration)
|
| 148 |
+
def gpu_convert(text: str | None = None, num_candidates: int | None = None, structured_fallback: bool | None = None) -> dict:
|
| 149 |
"""Convert a document and return the full conversion result.
|
| 150 |
|
| 151 |
Same pipeline as the UI conversion. Used by the /v1 OpenAI-style API routes.
|
|
|
|
| 639 |
#p-settings { background: transparent !important; border: 1px solid var(--hair-soft) !important; border-radius: 12px !important; margin-top: 4px; }
|
| 640 |
#p-settings > .label-wrap { font-family: var(--font-mono) !important; font-size: 0.68rem !important; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted) !important; }
|
| 641 |
#p-settings > .label-wrap .icon { color: var(--muted-2) !important; }
|
| 642 |
+
#p-settings .info-text { font-size: 0.72rem !important; color: var(--muted-2) !important; }
|
| 643 |
+
|
| 644 |
+
#p-candidates .wrap { display: inline-flex; gap: 4px; background: var(--panel); border: 1px solid var(--hair); border-radius: 100px; padding: 3px; }
|
| 645 |
+
#p-candidates label { border-radius: 100px; padding: 7px 16px; margin: 0 !important; cursor: pointer; transition: background .2s ease, color .2s ease; }
|
| 646 |
+
#p-candidates label span { font-family: var(--font-mono) !important; font-size: 11px !important; letter-spacing: 0.08em; color: var(--muted) !important; }
|
| 647 |
+
#p-candidates label.selected { background: rgba(255,255,255,0.08) !important; }
|
| 648 |
+
#p-candidates label.selected span { color: var(--warm) !important; }
|
| 649 |
+
#p-candidates input[type="radio"] { accent-color: var(--warm); }
|
| 650 |
#p-settings .p-label { margin-bottom: 4px; }
|
| 651 |
|
| 652 |
.p-foot {
|
|
|
|
| 696 |
elem_id="p-text",
|
| 697 |
)
|
| 698 |
with gr.Accordion("SETTINGS", open=False, elem_id="p-settings"):
|
| 699 |
+
candidates = gr.Radio(
|
| 700 |
+
choices=[1, 2, 3],
|
| 701 |
+
value=3,
|
| 702 |
+
type="value",
|
| 703 |
label="PASITA CANDIDATES",
|
| 704 |
info="More samples improve the reranker. 3 is the measured default.",
|
| 705 |
+
elem_id="p-candidates",
|
| 706 |
)
|
| 707 |
structured = gr.Checkbox(
|
| 708 |
value=True,
|