PK9129/FineWeb
0
1from __future__ import annotations2 3import html4import os5from functools import lru_cache6from pathlib import Path7 8HF_CACHE_ROOT = Path(".hf_cache").resolve()9HF_CACHE_ROOT.mkdir(parents=True, exist_ok=True)10os.environ.setdefault("HF_HOME", str(HF_CACHE_ROOT))11os.environ.setdefault("HF_HUB_CACHE", str(HF_CACHE_ROOT / "hub"))12os.environ.setdefault("TRANSFORMERS_NO_TF", "1")13os.environ.setdefault("USE_TF", "0")14os.environ.setdefault("USE_FLAX", "0")15 16import gradio as gr17import torch18 19from gpt2_inference import DEFAULT_CHECKPOINT_PATH, InferenceEngine20 21 22APP_NAME = os.getenv("APP_NAME", "FineWebGPT")23APP_SUBTITLE = os.getenv(24 "APP_SUBTITLE",25 "Decoder-only GPT-2 pretrained from scratch on FineWeb-Edu and served in full FP32.",26)27APP_DESCRIPTION = os.getenv(28 "APP_DESCRIPTION",29 "This Space showcases the pretrained checkpoint, the training story behind it, and a raw text-completion playground for direct testing.",30)31CHECKPOINT_PATH = os.getenv("MODEL_FILE", str(DEFAULT_CHECKPOINT_PATH))32RUNTIME_DEVICE = os.getenv("MODEL_DEVICE", "cuda" if torch.cuda.is_available() else "cpu")33MAX_HISTORY_MESSAGES = 1234 35CREATOR = {36 "name": os.getenv("CREATOR_NAME", "Priyanshu Kumar"),37 "title": os.getenv(38 "CREATOR_TITLE",39 "Built the architecture, pretraining pipeline, checkpoint export flow, inference stack, and deployment-ready app.",40 ),41 "bio": os.getenv(42 "CREATOR_BIO",43 "This project was built end to end by Priyanshu Kumar, from GPT-2 training on FineWeb-Edu to inference packaging and Hugging Face deployment.",44 ),45 "huggingface": os.getenv("CREATOR_HUGGINGFACE", "https://huggingface.co/PK9129"),46 "github": os.getenv("CREATOR_GITHUB", "https://github.com/Priya123nshu/GPT_2_124M"),47 "linkedin": os.getenv(48 "CREATOR_LINKEDIN",49 "https://www.linkedin.com/in/priyanshu-kumar-980b50179/",50 ),51 "portfolio": os.getenv("CREATOR_PORTFOLIO", "https://portfolio-vert-two-73.vercel.app/"),52 "article": os.getenv(53 "CREATOR_ARTICLE",54 "https://portfolio-vert-two-73.vercel.app/blogs/building-llm-from-scratch-gpt-style-decoder",55 ),56 "email": os.getenv("CREATOR_EMAIL", "priyanshu.altruist@gmail.com"),57}58 59PROMPT_SUGGESTIONS = [60 "The future of artificial intelligence is",61 "Write a short paragraph about why data quality matters for language models.",62 "Explain transformer attention in simple language.",63 "Pretraining from scratch teaches us that",64]65 66CSS = """67:root {68 --bg: #07090d;69 --bg-alt: #0d131b;70 --panel: rgba(13, 18, 27, 0.94);71 --panel-soft: rgba(18, 24, 35, 0.9);72 --panel-strong: rgba(10, 14, 21, 0.96);73 --line: rgba(125, 160, 220, 0.18);74 --line-strong: rgba(77, 215, 255, 0.22);75 --text: #f4f7fb;76 --muted: #9da9bf;77 --accent: #4dd7ff;78 --accent-warm: #f08b55;79 --accent-soft: #9db6ff;80 --success: #3fe0a2;81 --shadow: 0 24px 72px rgba(0, 0, 0, 0.4);82}83 84html, body {85 margin: 0;86 min-height: 100%;87 background:88 radial-gradient(circle at 12% 10%, rgba(77, 215, 255, 0.12), transparent 24%),89 radial-gradient(circle at 86% 12%, rgba(240, 139, 85, 0.12), transparent 20%),90 radial-gradient(circle at 70% 68%, rgba(157, 182, 255, 0.08), transparent 26%),91 linear-gradient(180deg, #07090d 0%, #091018 50%, #0b1017 100%);92 color: var(--text);93 overflow-x: hidden;94}95 96body, .gradio-container {97 font-family: "Segoe UI", "Trebuchet MS", sans-serif;98 color: var(--text);99}100 101.gradio-container {102 max-width: 1600px !important;103 margin: 0 auto !important;104 padding: 20px 18px 28px !important;105 background: transparent !important;106}107 108.gradio-container .main {109 padding: 0 !important;110}111 112#workspace {113 gap: 20px;114 align-items: start;115}116 117.rail {118 gap: 18px;119}120 121.rail > div,122.stage-column > div {123 min-width: 0;124}125 126.panel-card,127.hero-card,128#topbar,129#playground-shell {130 border: 1px solid var(--line);131 background: linear-gradient(180deg, rgba(16, 21, 31, 0.96), rgba(9, 13, 20, 0.95));132 border-radius: 26px;133 box-shadow: var(--shadow);134}135 136#topbar {137 display: flex;138 justify-content: space-between;139 gap: 20px;140 padding: 22px 26px;141 margin-bottom: 20px;142}143 144.brand-wrap {145 display: flex;146 gap: 18px;147 align-items: center;148 min-width: 0;149}150 151.brand-badge {152 width: 64px;153 height: 64px;154 border-radius: 22px;155 display: grid;156 place-items: center;157 background:158 linear-gradient(135deg, rgba(77, 215, 255, 0.92), rgba(157, 182, 255, 0.88));159 color: #041018;160 font-weight: 800;161 font-size: 1.2rem;162 letter-spacing: 0.08em;163 box-shadow: 0 18px 40px rgba(77, 215, 255, 0.24);164}165 166.eyebrow {167 color: var(--accent);168 font-size: 0.82rem;169 font-weight: 700;170 letter-spacing: 0.16em;171 text-transform: uppercase;172 margin-bottom: 8px;173}174 175.brand-copy h1 {176 margin: 0;177 font-family: Georgia, "Times New Roman", serif;178 font-size: clamp(2rem, 4vw, 3rem);179 line-height: 0.98;180 letter-spacing: 0.01em;181}182 183.brand-copy p {184 margin: 10px 0 0;185 color: var(--muted);186 max-width: 64ch;187 line-height: 1.65;188}189 190.runtime-pill {191 align-self: flex-start;192 display: inline-flex;193 align-items: center;194 gap: 10px;195 white-space: nowrap;196 border-radius: 999px;197 padding: 12px 16px;198 border: 1px solid rgba(63, 224, 162, 0.2);199 background: rgba(11, 25, 20, 0.84);200 color: #ecfff8;201 font-weight: 700;202}203 204.runtime-dot {205 width: 10px;206 height: 10px;207 border-radius: 50%;208 background: var(--success);209 box-shadow: 0 0 18px rgba(63, 224, 162, 0.72);210}211 212.panel-title {213 margin: 0 0 10px;214 color: var(--accent);215 font-size: 1.15rem;216 font-weight: 800;217 letter-spacing: 0.12em;218 text-transform: uppercase;219}220 221.panel-card {222 padding: 20px 22px;223}224 225.panel-copy {226 margin: 0 0 16px;227 color: var(--muted);228 line-height: 1.7;229}230 231.info-list {232 display: grid;233 gap: 12px;234}235 236.info-item strong {237 color: var(--text);238}239 240.info-item span {241 color: var(--muted);242 line-height: 1.65;243}244 245.hero-card {246 padding: 28px 28px 24px;247 margin-bottom: 18px;248 overflow: hidden;249 position: relative;250}251 252.hero-card::after {253 content: "";254 position: absolute;255 inset: auto -60px -80px auto;256 width: 220px;257 height: 220px;258 border-radius: 50%;259 background: radial-gradient(circle, rgba(77, 215, 255, 0.14), transparent 68%);260 pointer-events: none;261}262 263.hero-tag {264 display: inline-flex;265 align-items: center;266 gap: 8px;267 padding: 8px 12px;268 border-radius: 999px;269 border: 1px solid rgba(240, 139, 85, 0.18);270 background: rgba(32, 20, 16, 0.74);271 color: #ffd8c8;272 font-size: 0.84rem;273 font-weight: 700;274 letter-spacing: 0.08em;275 text-transform: uppercase;276}277 278.hero-card h2 {279 margin: 18px 0 10px;280 font-family: Georgia, "Times New Roman", serif;281 font-size: clamp(2rem, 3vw, 2.8rem);282 line-height: 1.02;283 max-width: 12ch;284}285 286.hero-card p {287 margin: 0;288 max-width: 62ch;289 color: var(--muted);290 line-height: 1.75;291}292 293.hero-signals {294 display: flex;295 flex-wrap: wrap;296 gap: 12px;297 margin-top: 22px;298}299 300.hero-signal {301 display: inline-flex;302 align-items: center;303 gap: 8px;304 padding: 10px 14px;305 border-radius: 999px;306 border: 1px solid var(--line);307 background: rgba(12, 17, 26, 0.9);308 color: #d8e5ff;309}310 311#playground-shell {312 padding: 18px;313}314 315.playground-head {316 display: flex;317 justify-content: space-between;318 gap: 16px;319 align-items: flex-start;320 margin-bottom: 16px;321}322 323.playground-head h3 {324 margin: 0;325 font-size: 1.05rem;326 letter-spacing: 0.1em;327 text-transform: uppercase;328 color: var(--accent);329}330 331.playground-head p {332 margin: 8px 0 0;333 color: var(--muted);334 line-height: 1.7;335}336 337.playground-note {338 max-width: 34ch;339 color: #d4dded;340 font-size: 0.92rem;341 line-height: 1.6;342}343 344#chatbot {345 border-radius: 22px !important;346 border: 1px solid var(--line-strong);347 background:348 linear-gradient(180deg, rgba(14, 18, 28, 0.98), rgba(8, 11, 17, 0.98)) !important;349 min-height: 430px;350 max-height: 430px;351 overflow: hidden;352}353 354#chatbot > .wrap,355#chatbot .bubble-wrap,356#chatbot .message-wrap {357 background: transparent !important;358}359 360#chatbot .message.user {361 background: linear-gradient(135deg, rgba(77, 215, 255, 0.14), rgba(157, 182, 255, 0.18)) !important;362 border: 1px solid rgba(157, 182, 255, 0.18) !important;363}364 365#chatbot .message.bot {366 background: rgba(17, 22, 32, 0.94) !important;367 border: 1px solid rgba(77, 215, 255, 0.12) !important;368}369 370#prompt-box textarea {371 min-height: 92px !important;372 max-height: 132px !important;373 background: rgba(13, 18, 26, 0.98) !important;374 color: var(--text) !important;375 border: 1px solid var(--line) !important;376 border-radius: 20px !important;377}378 379.chip-row {380 display: flex;381 flex-wrap: wrap;382 gap: 10px;383 margin: 14px 0 12px;384}385 386.prompt-chip button {387 border-radius: 999px !important;388 border: 1px solid rgba(77, 215, 255, 0.16) !important;389 background: rgba(15, 20, 30, 0.96) !important;390 color: #dbe7ff !important;391 min-height: 40px !important;392 padding: 0 14px !important;393}394 395.prompt-chip button:hover {396 border-color: rgba(77, 215, 255, 0.34) !important;397 background: rgba(20, 27, 39, 0.98) !important;398}399 400.control-grid {401 gap: 12px;402 margin-top: 4px;403}404 405.control-grid > div {406 min-width: 0;407}408 409.control-grid label {410 color: var(--muted) !important;411}412 413.metrics-card {414 display: grid;415 grid-template-columns: repeat(3, minmax(0, 1fr));416 gap: 12px;417 margin-top: 16px;418}419 420.metric-block {421 border-radius: 18px;422 border: 1px solid rgba(77, 215, 255, 0.1);423 background: rgba(9, 13, 20, 0.96);424 padding: 14px;425}426 427.metric-block span {428 display: block;429 color: var(--muted);430 font-size: 0.76rem;431 letter-spacing: 0.12em;432 text-transform: uppercase;433 margin-bottom: 8px;434}435 436.metric-block strong {437 font-size: 1.04rem;438}439 440.action-row {441 gap: 12px;442}443 444#send-btn button,445#clear-btn button {446 min-height: 50px !important;447 border-radius: 18px !important;448}449 450#send-btn button {451 border: none !important;452 background: linear-gradient(135deg, #4dd7ff, #9db6ff) !important;453 color: #07111a !important;454 font-weight: 800 !important;455}456 457#clear-btn button {458 border: 1px solid var(--line) !important;459 background: rgba(14, 19, 28, 0.98) !important;460 color: var(--text) !important;461}462 463.link-grid {464 display: flex;465 flex-wrap: wrap;466 gap: 10px;467 margin-top: 14px;468}469 470.link-grid a {471 text-decoration: none;472 color: #dcebff;473 padding: 10px 14px;474 border-radius: 999px;475 border: 1px solid rgba(77, 215, 255, 0.18);476 background: rgba(12, 18, 27, 0.98);477}478 479.link-grid a:hover {480 border-color: rgba(77, 215, 255, 0.34);481}482 483footer {484 display: none !important;485}486 487@media (max-width: 1300px) {488 .metrics-card {489 grid-template-columns: 1fr;490 }491}492 493@media (max-width: 1100px) {494 #topbar,495 .playground-head {496 flex-direction: column;497 }498}499"""500 501 502@lru_cache(maxsize=1)503def get_engine() -> InferenceEngine:504 return InferenceEngine(checkpoint_path=CHECKPOINT_PATH, device=RUNTIME_DEVICE)505 506 507ENGINE = get_engine()508ARCHIVE = ENGINE.archive509MODEL_CONFIG = ENGINE.config510TRAINING_CONFIG = ARCHIVE.payload["config"]511 512 513def safe(text: object) -> str:514 return html.escape(str(text))515 516 517def format_number(value: int | float) -> str:518 return f"{int(value):,}"519 520 521def render_rows(rows: list[tuple[str, str]]) -> str:522 body = []523 for label, value in rows:524 body.append(525 "<div class='info-item'>"526 f"<strong>{safe(label)}:</strong> "527 f"<span>{safe(value)}</span>"528 "</div>"529 )530 return "<div class='info-list'>" + "".join(body) + "</div>"531 532 533def render_panel(title: str, rows: list[tuple[str, str]], copy: str | None = None) -> str:534 copy_html = f"<p class='panel-copy'>{safe(copy)}</p>" if copy else ""535 return (536 f"<div class='panel-title'>{safe(title)}</div>"537 "<div class='panel-card'>"538 f"{copy_html}"539 f"{render_rows(rows)}"540 "</div>"541 )542 543 544def render_link_grid(link_items: list[tuple[str, str]]) -> str:545 visible = [(label, url) for label, url in link_items if url]546 if not visible:547 return ""548 links = [549 f"<a href='{safe(url)}' target='_blank' rel='noopener noreferrer'>{safe(label)}</a>"550 for label, url in visible551 ]552 return "<div class='link-grid'>" + "".join(links) + "</div>"553 554 555def render_topbar() -> str:556 runtime_label = "Online | GPU" if RUNTIME_DEVICE.startswith("cuda") else "Online | CPU"557 return (558 "<div id='topbar'>"559 "<div class='brand-wrap'>"560 "<div class='brand-badge'>FG</div>"561 "<div class='brand-copy'>"562 "<div class='eyebrow'>From-scratch pretraining</div>"563 f"<h1>{safe(APP_NAME)}</h1>"564 f"<p>{safe(APP_SUBTITLE)}</p>"565 "</div>"566 "</div>"567 "<div class='runtime-pill'>"568 "<span class='runtime-dot'></span>"569 f"{safe(runtime_label)} | FP32"570 "</div>"571 "</div>"572 )573 574 575def render_hero() -> str:576 signals = [577 "393.2M tokens",578 "12,000 steps",579 "GPT-2 small",580 "1024-token context",581 ]582 signal_html = "".join(f"<span class='hero-signal'>{safe(item)}</span>" for item in signals)583 return (584 "<div class='hero-card'>"585 "<div class='hero-tag'>Base model showcase</div>"586 f"<h2>{safe(APP_NAME)}</h2>"587 f"<p>{safe(APP_DESCRIPTION)}</p>"588 f"<div class='hero-signals'>{signal_html}</div>"589 "</div>"590 )591 592 593def render_model_info() -> str:594 rows = [595 ("Name", APP_NAME),596 ("Architecture", "GPT-2"),597 ("Parameters", "~124M"),598 ("Training Type", "From-scratch pretraining"),599 ("Dataset", f"{ARCHIVE.dataset_id} / {ARCHIVE.dataset_name}"),600 ("Objective", "Causal language modeling"),601 ("Tokens Seen", format_number(ARCHIVE.tokens_seen)),602 ("Training Step", format_number(ARCHIVE.global_step)),603 ("Tokenizer", str(TRAINING_CONFIG["tokenizer_name"])),604 ("Inference", f"FP32 on {RUNTIME_DEVICE.upper()}"),605 ]606 return render_panel("Model Information", rows)607 608 609def render_training_details() -> str:610 rows = [611 ("Context Window", f"{MODEL_CONFIG.context_length} tokens"),612 ("Layers / Heads", f"{MODEL_CONFIG.n_layers} / {MODEL_CONFIG.n_heads}"),613 ("Hidden Size", str(MODEL_CONFIG.d_model)),614 ("MLP Hidden Size", str(MODEL_CONFIG.mlp_hidden_dim)),615 ("Micro Batch", str(TRAINING_CONFIG["micro_batch_size"])),616 ("Grad Accumulation", str(TRAINING_CONFIG["grad_accum_steps"])),617 ("Learning Rate", str(TRAINING_CONFIG["lr"])),618 ("Warmup Steps", str(TRAINING_CONFIG["warmup_steps"])),619 ("Target Tokens", format_number(TRAINING_CONFIG["target_tokens"])),620 ("Checkpoint Source", os.path.basename(CHECKPOINT_PATH)),621 ]622 return render_panel(623 "Training Details",624 rows,625 copy="This checkpoint comes from a full GPT-2 pretraining run on FineWeb-Edu and is served here as a raw completion model rather than a chat-tuned assistant.",626 )627 628 629def render_capabilities() -> str:630 rows = [631 ("Best Use", "Prompt continuation and base-model quality inspection"),632 ("Strengths", "Fluent continuation, topical carryover, and generative range"),633 ("Not Tuned For", "Instruction following, tool use, or RLHF-style safety layers"),634 ("Limitations", "Can drift, hallucinate, and operate only within a 1024-token context"),635 ]636 return render_panel(637 f"What {APP_NAME} Does",638 rows,639 copy="Think of this as a pretrained text engine and project showcase. It is meant to demonstrate what the model learned during pretraining, not to imitate a heavily aligned assistant.",640 )641 642 643def render_creator() -> str:644 rows = [645 ("Creator", CREATOR["name"]),646 ("Role", CREATOR["title"]),647 ]648 links = [649 ("GitHub", CREATOR["github"]),650 ("LinkedIn", CREATOR["linkedin"]),651 ("Portfolio", CREATOR["portfolio"]),652 ("Article", CREATOR["article"]),653 ("Hugging Face", CREATOR["huggingface"]),654 ("Email", f"mailto:{CREATOR['email']}" if CREATOR["email"] else ""),655 ]656 return (657 "<div class='panel-title'>About The Creator</div>"658 "<div class='panel-card'>"659 f"<p class='panel-copy'>{safe(CREATOR['bio'])}</p>"660 f"{render_rows(rows)}"661 f"{render_link_grid(links)}"662 "</div>"663 )664 665 666def render_project_links() -> str:667 rows = [668 ("Repository", "GPT_2_124M"),669 ("Deployment", "Hugging Face Space"),670 ("Article", "Building LLM from Scratch, GPT-style Decoder"),671 ]672 links = [673 ("Source Code", CREATOR["github"]),674 ("Read Article", CREATOR["article"]),675 ("Portfolio", CREATOR["portfolio"]),676 ]677 return (678 "<div class='panel-title'>Project Links</div>"679 "<div class='panel-card'>"680 "<p class='panel-copy'>Explore the repo, the article that documents the training journey, and the rest of the creator's work.</p>"681 f"{render_rows(rows)}"682 f"{render_link_grid(links)}"683 "</div>"684 )685 686 687def render_metrics(result: dict[str, object] | None = None) -> str:688 if result is None:689 generated_tokens = "-"690 latency = "-"691 throughput = "-"692 else:693 generated_tokens = str(result["generated_tokens"])694 latency = f"{float(result['elapsed_seconds']):.2f} s"695 tokens_per_second = result["tokens_per_second"]696 throughput = "-" if tokens_per_second is None else f"{float(tokens_per_second):.2f}"697 return (698 "<div class='metrics-card'>"699 f"<div class='metric-block'><span>Generated Tokens</span><strong>{safe(generated_tokens)}</strong></div>"700 f"<div class='metric-block'><span>Latency</span><strong>{safe(latency)}</strong></div>"701 f"<div class='metric-block'><span>Tokens / sec</span><strong>{safe(throughput)}</strong></div>"702 "</div>"703 )704 705 706def render_playground_head() -> str:707 return (708 "<div class='playground-head'>"709 "<div>"710 "<h3>Completion Playground</h3>"711 "<p>Enter a prompt and test the pretrained checkpoint directly. The response below is the model continuation, not a separate instruction-tuned wrapper.</p>"712 "</div>"713 "<div class='playground-note'>CPU Spaces will be slower than GPU runs, but the model remains in full FP32 precision.</div>"714 "</div>"715 )716 717 718def set_prompt(value: str) -> str:719 return value720 721 722def generate_reply(723 prompt: str,724 history: list[dict[str, str]] | None,725 temperature: float,726 top_k: int,727 max_new_tokens: int,728 seed: float | None,729):730 history = history or []731 cleaned_prompt = (prompt or "").strip()732 if not cleaned_prompt:733 return history, "", render_metrics()734 735 try:736 result = get_engine().generate(737 prompt=cleaned_prompt,738 temperature=float(temperature),739 top_k=int(top_k),740 max_new_tokens=int(max_new_tokens),741 seed=None if seed in (None, "") else int(seed),742 )743 assistant_text = result["completion"] or result["text"] or "(No text generated.)"744 history = history + [745 {"role": "user", "content": cleaned_prompt},746 {"role": "assistant", "content": assistant_text},747 ]748 history = history[-MAX_HISTORY_MESSAGES:]749 return history, "", render_metrics(result)750 except Exception as exc:751 history = history + [752 {"role": "user", "content": cleaned_prompt},753 {"role": "assistant", "content": f"Generation failed: {exc}"},754 ]755 history = history[-MAX_HISTORY_MESSAGES:]756 return history, "", render_metrics()757 758 759def reset_chat():760 return [], "", render_metrics()761 762 763with gr.Blocks(title=APP_NAME, fill_height=False, fill_width=True) as demo:764 gr.HTML(render_topbar())765 766 with gr.Row(elem_id="workspace"):767 with gr.Column(scale=3, min_width=290, elem_classes=["rail"]):768 gr.HTML(render_model_info())769 gr.HTML(render_training_details())770 771 with gr.Column(scale=5, min_width=720, elem_classes=["stage-column"]):772 gr.HTML(render_hero())773 with gr.Group(elem_id="playground-shell"):774 gr.HTML(render_playground_head())775 chatbot = gr.Chatbot(776 value=[],777 elem_id="chatbot",778 show_label=False,779 height=430,780 layout="bubble",781 )782 prompt_box = gr.Textbox(783 placeholder="Type your prompt here...",784 show_label=False,785 elem_id="prompt-box",786 lines=4,787 )788 with gr.Row(elem_classes=["chip-row"]):789 prompt_buttons = []790 for idx, suggestion in enumerate(PROMPT_SUGGESTIONS):791 button = gr.Button(792 suggestion,793 elem_id=f"prompt-chip-{idx}",794 elem_classes=["prompt-chip"],795 variant="secondary",796 )797 prompt_buttons.append((button, suggestion))798 799 with gr.Row(elem_classes=["control-grid"]):800 temperature = gr.Slider(0.0, 1.5, value=0.8, step=0.1, label="Temperature")801 top_k = gr.Slider(0, 100, value=50, step=1, label="Top-k")802 max_new_tokens = gr.Slider(16, 256, value=96, step=8, label="Max New Tokens")803 seed = gr.Number(value=1337, label="Seed", precision=0)804 805 with gr.Row(elem_classes=["action-row"]):806 send_button = gr.Button("Generate", elem_id="send-btn")807 clear_button = gr.Button("Clear", elem_id="clear-btn")808 809 metrics = gr.HTML(render_metrics())810 811 with gr.Column(scale=3, min_width=290, elem_classes=["rail"]):812 gr.HTML(render_capabilities())813 gr.HTML(render_creator())814 gr.HTML(render_project_links())815 816 for button, suggestion in prompt_buttons:817 button.click(fn=lambda s=suggestion: set_prompt(s), outputs=prompt_box)818 819 send_button.click(820 fn=generate_reply,821 inputs=[prompt_box, chatbot, temperature, top_k, max_new_tokens, seed],822 outputs=[chatbot, prompt_box, metrics],823 )824 prompt_box.submit(825 fn=generate_reply,826 inputs=[prompt_box, chatbot, temperature, top_k, max_new_tokens, seed],827 outputs=[chatbot, prompt_box, metrics],828 )829 clear_button.click(fn=reset_chat, outputs=[chatbot, prompt_box, metrics])830 831demo.queue(default_concurrency_limit=1)832 833 834if __name__ == "__main__":835 demo.launch(836 server_name=os.getenv("GRADIO_SERVER_NAME", "0.0.0.0"),837 server_port=int(os.getenv("PORT", "7860")),838 theme=gr.themes.Base(),839 css=CSS,840 )841 