Update app.py
Browse files
app.py
CHANGED
|
@@ -21,6 +21,7 @@ from forgekit.config_generator import (
|
|
| 21 |
)
|
| 22 |
from forgekit.notebook_generator import generate_merge_notebook, save_notebook
|
| 23 |
from forgekit.ai_advisor import merge_advisor, model_describer, config_explainer
|
|
|
|
| 24 |
|
| 25 |
# ===== THEME =====
|
| 26 |
theme = gr.themes.Base(
|
|
@@ -627,12 +628,12 @@ license: apache-2.0
|
|
| 627 |
# =====================================================
|
| 628 |
with gr.Tab("π€ AI Advisor", id="ai"):
|
| 629 |
gr.Markdown("""### AI-Powered Merge Intelligence
|
| 630 |
-
Get smart recommendations, capability predictions, and plain-English explanations β powered by
|
| 631 |
|
| 632 |
-
|
| 633 |
-
label="
|
| 634 |
type="password",
|
| 635 |
-
placeholder="
|
| 636 |
)
|
| 637 |
|
| 638 |
with gr.Tabs():
|
|
@@ -652,7 +653,7 @@ license: apache-2.0
|
|
| 652 |
ai_advise_out = gr.Markdown()
|
| 653 |
|
| 654 |
ai_advise_btn.click(
|
| 655 |
-
merge_advisor, [ai_models, ai_goal,
|
| 656 |
)
|
| 657 |
|
| 658 |
# --- Model Describer ---
|
|
@@ -669,7 +670,7 @@ license: apache-2.0
|
|
| 669 |
desc_out = gr.Markdown()
|
| 670 |
|
| 671 |
desc_btn.click(
|
| 672 |
-
model_describer, [desc_models, desc_method, desc_weights,
|
| 673 |
)
|
| 674 |
|
| 675 |
# --- Config Explainer ---
|
|
@@ -699,11 +700,139 @@ dtype: bfloat16""",
|
|
| 699 |
explain_out = gr.Markdown()
|
| 700 |
|
| 701 |
explain_btn.click(
|
| 702 |
-
config_explainer, [explain_yaml,
|
| 703 |
)
|
| 704 |
|
| 705 |
# =====================================================
|
| 706 |
-
# TAB 6:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 707 |
# =====================================================
|
| 708 |
with gr.Tab("π Leaderboard", id="leaderboard"):
|
| 709 |
gr.Markdown("""### Community Merge Leaderboard
|
|
|
|
| 21 |
)
|
| 22 |
from forgekit.notebook_generator import generate_merge_notebook, save_notebook
|
| 23 |
from forgekit.ai_advisor import merge_advisor, model_describer, config_explainer
|
| 24 |
+
from forgekit.kaggle_runner import push_and_run_kernel, check_kernel_status, generate_kaggle_notebook
|
| 25 |
|
| 26 |
# ===== THEME =====
|
| 27 |
theme = gr.themes.Base(
|
|
|
|
| 628 |
# =====================================================
|
| 629 |
with gr.Tab("π€ AI Advisor", id="ai"):
|
| 630 |
gr.Markdown("""### AI-Powered Merge Intelligence
|
| 631 |
+
Get smart recommendations, capability predictions, and plain-English explanations β powered by **Llama 3.3 70B** on Groq (free, blazing fast).""")
|
| 632 |
|
| 633 |
+
groq_key = gr.Textbox(
|
| 634 |
+
label="Groq API Key (free at console.groq.com)",
|
| 635 |
type="password",
|
| 636 |
+
placeholder="gsk_... (free, no credit card needed)",
|
| 637 |
)
|
| 638 |
|
| 639 |
with gr.Tabs():
|
|
|
|
| 653 |
ai_advise_out = gr.Markdown()
|
| 654 |
|
| 655 |
ai_advise_btn.click(
|
| 656 |
+
merge_advisor, [ai_models, ai_goal, groq_key], ai_advise_out
|
| 657 |
)
|
| 658 |
|
| 659 |
# --- Model Describer ---
|
|
|
|
| 670 |
desc_out = gr.Markdown()
|
| 671 |
|
| 672 |
desc_btn.click(
|
| 673 |
+
model_describer, [desc_models, desc_method, desc_weights, groq_key], desc_out
|
| 674 |
)
|
| 675 |
|
| 676 |
# --- Config Explainer ---
|
|
|
|
| 700 |
explain_out = gr.Markdown()
|
| 701 |
|
| 702 |
explain_btn.click(
|
| 703 |
+
config_explainer, [explain_yaml, groq_key], explain_out
|
| 704 |
)
|
| 705 |
|
| 706 |
# =====================================================
|
| 707 |
+
# TAB 6: KAGGLE RUNNER
|
| 708 |
+
# =====================================================
|
| 709 |
+
with gr.Tab("π Run on Kaggle", id="kaggle"):
|
| 710 |
+
gr.Markdown("""### Run Your Merge on Kaggle's Free GPU
|
| 711 |
+
Push your merge notebook directly to Kaggle and run it on a free T4 GPU β no local setup needed.
|
| 712 |
+
|
| 713 |
+
**You need:** A [Kaggle account](https://www.kaggle.com) with an API token. Go to *Settings > API > Create New Token*.""")
|
| 714 |
+
|
| 715 |
+
with gr.Row():
|
| 716 |
+
with gr.Column():
|
| 717 |
+
kg_username = gr.Textbox(label="Kaggle Username", placeholder="your_kaggle_username")
|
| 718 |
+
kg_key = gr.Textbox(label="Kaggle API Key", type="password", placeholder="From kaggle.json")
|
| 719 |
+
with gr.Column():
|
| 720 |
+
kg_hf_note = gr.Markdown("""**Important:** Add your HF token as a Kaggle Secret:
|
| 721 |
+
1. Go to your kernel's **Settings** tab
|
| 722 |
+
2. Under **Secrets**, add `HF_TOKEN` with your HuggingFace token
|
| 723 |
+
3. This lets the kernel download gated models and upload results""")
|
| 724 |
+
|
| 725 |
+
gr.Markdown("---")
|
| 726 |
+
gr.Markdown("#### Configure Merge (or use settings from Merge Builder tab)")
|
| 727 |
+
|
| 728 |
+
with gr.Row():
|
| 729 |
+
kg_models = gr.Textbox(
|
| 730 |
+
label="Models (one per line)", lines=4,
|
| 731 |
+
placeholder="Qwen/Qwen2.5-Coder-7B-Instruct\nQwen/Qwen2.5-Math-7B-Instruct",
|
| 732 |
+
)
|
| 733 |
+
with gr.Column():
|
| 734 |
+
kg_method = gr.Dropdown(choices=list(MERGE_METHODS.keys()), value="dare_ties", label="Method")
|
| 735 |
+
kg_base = gr.Textbox(label="Base Model", placeholder="Qwen/Qwen2.5-7B-Instruct")
|
| 736 |
+
kg_weights = gr.Textbox(label="Weights", placeholder="0.5, 0.5")
|
| 737 |
+
kg_densities = gr.Textbox(label="Densities", placeholder="0.7, 0.6")
|
| 738 |
+
|
| 739 |
+
with gr.Row():
|
| 740 |
+
kg_output_name = gr.Textbox(label="Output Model Name", placeholder="My-Merged-7B", value="ForgeKit-Merge")
|
| 741 |
+
kg_hf_user = gr.Textbox(label="HF Username (for upload)", placeholder="AIencoder")
|
| 742 |
+
|
| 743 |
+
kg_run_btn = gr.Button("π Push & Run on Kaggle", variant="primary", size="lg")
|
| 744 |
+
kg_status = gr.Markdown()
|
| 745 |
+
|
| 746 |
+
def run_on_kaggle(
|
| 747 |
+
username, key, models_text, method, base, weights_text, densities_text,
|
| 748 |
+
output_name, hf_user,
|
| 749 |
+
):
|
| 750 |
+
# Build config
|
| 751 |
+
models = [m.strip() for m in models_text.strip().split("\n") if m.strip()]
|
| 752 |
+
if len(models) < 2:
|
| 753 |
+
return "Add at least 2 models."
|
| 754 |
+
|
| 755 |
+
weights = []
|
| 756 |
+
if weights_text.strip():
|
| 757 |
+
try:
|
| 758 |
+
weights = [float(w.strip()) for w in weights_text.split(",")]
|
| 759 |
+
except ValueError:
|
| 760 |
+
return "Invalid weights."
|
| 761 |
+
|
| 762 |
+
densities = []
|
| 763 |
+
if densities_text.strip():
|
| 764 |
+
try:
|
| 765 |
+
densities = [float(d.strip()) for d in densities_text.split(",")]
|
| 766 |
+
except ValueError:
|
| 767 |
+
return "Invalid densities."
|
| 768 |
+
|
| 769 |
+
config = MergeConfig(
|
| 770 |
+
method=method,
|
| 771 |
+
models=models,
|
| 772 |
+
base_model=base.strip(),
|
| 773 |
+
weights=weights,
|
| 774 |
+
densities=densities,
|
| 775 |
+
)
|
| 776 |
+
|
| 777 |
+
name = output_name.strip() or "ForgeKit-Merge"
|
| 778 |
+
|
| 779 |
+
# Generate notebook
|
| 780 |
+
nb = generate_merge_notebook(
|
| 781 |
+
config,
|
| 782 |
+
output_model_name=name,
|
| 783 |
+
hf_username=hf_user.strip(),
|
| 784 |
+
include_quantize=True,
|
| 785 |
+
include_deploy=False,
|
| 786 |
+
quant_types=["Q5_K_M", "Q4_K_M"],
|
| 787 |
+
)
|
| 788 |
+
|
| 789 |
+
# Adapt for Kaggle
|
| 790 |
+
kaggle_nb_json = generate_kaggle_notebook(nb)
|
| 791 |
+
|
| 792 |
+
# Push to Kaggle
|
| 793 |
+
result = push_and_run_kernel(
|
| 794 |
+
notebook_json=kaggle_nb_json,
|
| 795 |
+
kernel_title=f"ForgeKit-{name}",
|
| 796 |
+
kaggle_username=username.strip(),
|
| 797 |
+
kaggle_key=key.strip(),
|
| 798 |
+
enable_gpu=True,
|
| 799 |
+
enable_internet=True,
|
| 800 |
+
)
|
| 801 |
+
|
| 802 |
+
if result["success"]:
|
| 803 |
+
return result["message"]
|
| 804 |
+
else:
|
| 805 |
+
return result["error"]
|
| 806 |
+
|
| 807 |
+
kg_run_btn.click(
|
| 808 |
+
run_on_kaggle,
|
| 809 |
+
[kg_username, kg_key, kg_models, kg_method, kg_base, kg_weights, kg_densities,
|
| 810 |
+
kg_output_name, kg_hf_user],
|
| 811 |
+
kg_status,
|
| 812 |
+
)
|
| 813 |
+
|
| 814 |
+
gr.Markdown("---")
|
| 815 |
+
gr.Markdown("#### Check Kernel Status")
|
| 816 |
+
with gr.Row():
|
| 817 |
+
kg_check_slug = gr.Textbox(label="Kernel Slug", placeholder="username/forgekit-my-merged-7b")
|
| 818 |
+
kg_check_btn = gr.Button("π Check Status", variant="secondary")
|
| 819 |
+
kg_check_out = gr.Markdown()
|
| 820 |
+
|
| 821 |
+
def check_status(slug, username, key):
|
| 822 |
+
if not slug.strip():
|
| 823 |
+
return "Enter a kernel slug (username/kernel-name)"
|
| 824 |
+
result = check_kernel_status(slug.strip(), username.strip(), key.strip())
|
| 825 |
+
if result["success"]:
|
| 826 |
+
msg = result["display"]
|
| 827 |
+
if result.get("failure_message"):
|
| 828 |
+
msg += f"\n\nError: {result['failure_message']}"
|
| 829 |
+
return msg
|
| 830 |
+
return result["error"]
|
| 831 |
+
|
| 832 |
+
kg_check_btn.click(check_status, [kg_check_slug, kg_username, kg_key], kg_check_out)
|
| 833 |
+
|
| 834 |
+
# =====================================================
|
| 835 |
+
# TAB 7: LEADERBOARD
|
| 836 |
# =====================================================
|
| 837 |
with gr.Tab("π Leaderboard", id="leaderboard"):
|
| 838 |
gr.Markdown("""### Community Merge Leaderboard
|