fastchrf / app.py
jvamvas's picture
Deploy fastChrF Gradio demo with default and aggregate modes
3f5326b verified
Raw
History Blame Contribute Delete
4.4 kB
import json
import gradio as gr
import numpy as np
from fastchrf import aggregate_chrf, pairwise_chrf
def parse_lines(text: str) -> list[str]:
lines = [line.strip() for line in text.splitlines() if line.strip()]
if not lines:
raise gr.Error("Provide at least one non-empty line.")
return lines
def compute_chrf(
mode: str,
hypotheses_text: str,
references_text: str,
char_order: int,
beta: float,
remove_whitespace: bool,
eps_smoothing: bool,
) -> str:
hypotheses = parse_lines(hypotheses_text)
references = parse_lines(references_text)
if mode == "default":
scores = pairwise_chrf(
[hypotheses],
[references],
char_order=char_order,
beta=beta,
remove_whitespace=remove_whitespace,
eps_smoothing=eps_smoothing,
)
array = np.array(scores[0])
payload = {
"mode": "default",
"shape": list(array.shape),
"scores": array.tolist(),
"hypotheses": hypotheses,
"references": references,
}
else:
scores = aggregate_chrf(
[hypotheses],
[references],
char_order=char_order,
beta=beta,
remove_whitespace=remove_whitespace,
eps_smoothing=eps_smoothing,
)
array = np.array(scores[0])
payload = {
"mode": "aggregate",
"shape": list(array.shape),
"scores": array.tolist(),
"hypotheses": hypotheses,
"references": references,
}
return json.dumps(payload, indent=2, ensure_ascii=False)
EXAMPLE_HYPOTHESES = """The cat sat on the mat.
The cat sat on the hat."""
EXAMPLE_REFERENCES = """The cat sat on the mat.
The fat cat sat on the mat.
A cat sat on a mat."""
with gr.Blocks(title="fastChrF") as demo:
gr.Markdown(
"""
# fastChrF
Fast sentence-level ChrF for Minimum Bayes Risk decoding.
- **Default (pairwise):** ChrF between each hypothesis and each reference.
- **Aggregate:** Streamlined variant that aggregates across references.
[GitHub](https://github.com/jvamvas/fastChrF) · [Paper](https://arxiv.org/abs/2402.04251)
"""
)
with gr.Row():
mode = gr.Radio(
choices=["default", "aggregate"],
value="default",
label="Mode",
info="Default (pairwise) returns a hypothesis × reference matrix; aggregate returns one score per hypothesis.",
)
with gr.Row():
hypotheses = gr.Textbox(
label="Hypotheses (one per line)",
lines=8,
placeholder="Enter one hypothesis per line",
value=EXAMPLE_HYPOTHESES,
)
references = gr.Textbox(
label="References (one per line)",
lines=8,
placeholder="Enter one reference per line",
value=EXAMPLE_REFERENCES,
)
with gr.Accordion("Advanced options", open=False):
with gr.Row():
char_order = gr.Slider(
minimum=1,
maximum=10,
value=6,
step=1,
label="Character n-gram order",
)
beta = gr.Slider(
minimum=0.1,
maximum=5.0,
value=2.0,
step=0.1,
label="Beta (F-score weight)",
)
with gr.Row():
remove_whitespace = gr.Checkbox(value=True, label="Remove whitespace")
eps_smoothing = gr.Checkbox(value=False, label="Epsilon smoothing")
compute_button = gr.Button("Compute ChrF", variant="primary")
output = gr.Code(label="Results (JSON)", language="json", lines=20)
compute_button.click(
fn=compute_chrf,
inputs=[
mode,
hypotheses,
references,
char_order,
beta,
remove_whitespace,
eps_smoothing,
],
outputs=output,
)
gr.Examples(
examples=[
[EXAMPLE_HYPOTHESES, EXAMPLE_REFERENCES, "default"],
[EXAMPLE_HYPOTHESES, EXAMPLE_REFERENCES, "aggregate"],
],
inputs=[hypotheses, references, mode],
label="Examples",
)
if __name__ == "__main__":
demo.launch()