Update app.py
Browse filesLead capture + email cta fix v2
app.py
CHANGED
|
@@ -1 +1,214 @@
|
|
| 1 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
import requests
|
| 3 |
+
import os
|
| 4 |
+
|
| 5 |
+
NL = chr(10)
|
| 6 |
+
|
| 7 |
+
# Map user-facing modality choices to HF Hub task tags
|
| 8 |
+
TASK_MAP = {
|
| 9 |
+
"Text in -> text out": ["text-generation", "text2text-generation"],
|
| 10 |
+
"Images in (docs, UI, scans)": ["image-to-text", "visual-question-answering"],
|
| 11 |
+
"Audio in (speech)": ["automatic-speech-recognition"],
|
| 12 |
+
"Structured data (tables, logs)": ["tabular-classification", "tabular-regression"],
|
| 13 |
+
"Code": ["text-generation"],
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
LICENSE_FILTER = {
|
| 17 |
+
"Standard SaaS API is fine": None,
|
| 18 |
+
"Must stay in a specific cloud region": None,
|
| 19 |
+
"Strict: prefer on-prem / VPC only": "apache-2.0",
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
def fetch_top_models(tasks, license_filter=None, top_n=5):
|
| 23 |
+
seen = set()
|
| 24 |
+
results = []
|
| 25 |
+
for task in tasks:
|
| 26 |
+
try:
|
| 27 |
+
params = {
|
| 28 |
+
"pipeline_tag": task,
|
| 29 |
+
"sort": "downloads",
|
| 30 |
+
"direction": "-1",
|
| 31 |
+
"limit": "20",
|
| 32 |
+
}
|
| 33 |
+
if license_filter:
|
| 34 |
+
params["license"] = license_filter
|
| 35 |
+
resp = requests.get(
|
| 36 |
+
"https://huggingface.co/api/models",
|
| 37 |
+
params=params,
|
| 38 |
+
timeout=15,
|
| 39 |
+
)
|
| 40 |
+
if resp.status_code == 200:
|
| 41 |
+
data = resp.json()
|
| 42 |
+
for m in data:
|
| 43 |
+
mid = m.get("modelId", m.get("id", ""))
|
| 44 |
+
if mid and mid not in seen:
|
| 45 |
+
seen.add(mid)
|
| 46 |
+
downloads = m.get("downloads", 0) or 0
|
| 47 |
+
likes = m.get("likes", 0) or 0
|
| 48 |
+
results.append((mid, task, downloads, likes))
|
| 49 |
+
if len(results) >= top_n * len(tasks):
|
| 50 |
+
break
|
| 51 |
+
except Exception:
|
| 52 |
+
pass
|
| 53 |
+
|
| 54 |
+
results.sort(key=lambda x: x[2], reverse=True)
|
| 55 |
+
return results[:top_n]
|
| 56 |
+
|
| 57 |
+
def format_model_table(models):
|
| 58 |
+
if not models:
|
| 59 |
+
return "No models found via HF API. Please try again."
|
| 60 |
+
|
| 61 |
+
header = "| # | Model | Task | Downloads | Likes |" + NL
|
| 62 |
+
header += "|---|-------|------|-----------|-------|" + NL
|
| 63 |
+
rows = ""
|
| 64 |
+
for i, (mid, task, dl, lk) in enumerate(models, 1):
|
| 65 |
+
dl_fmt = f"{dl:,}" if dl else "N/A"
|
| 66 |
+
lk_fmt = f"{lk:,}" if lk else "N/A"
|
| 67 |
+
rows += f"| {i} | [{mid}](https://huggingface.co/{mid}) | `{task}` | {dl_fmt} | {lk_fmt} |" + NL
|
| 68 |
+
return header + rows
|
| 69 |
+
|
| 70 |
+
def recommend_model(
|
| 71 |
+
modality, outputs, domains, data_sensitivity, volume, latency, context_size, customization
|
| 72 |
+
):
|
| 73 |
+
# Collect HF tasks to query
|
| 74 |
+
hf_tasks = []
|
| 75 |
+
for m in modality:
|
| 76 |
+
hf_tasks.extend(TASK_MAP.get(m, []))
|
| 77 |
+
|
| 78 |
+
# Deduplicate, keep order
|
| 79 |
+
seen_t = set()
|
| 80 |
+
unique_tasks = []
|
| 81 |
+
for t in hf_tasks:
|
| 82 |
+
if t not in seen_t:
|
| 83 |
+
seen_t.add(t)
|
| 84 |
+
unique_tasks.append(t)
|
| 85 |
+
|
| 86 |
+
if not unique_tasks:
|
| 87 |
+
unique_tasks = ["text-generation"]
|
| 88 |
+
|
| 89 |
+
license_filter = LICENSE_FILTER.get(data_sensitivity)
|
| 90 |
+
|
| 91 |
+
# Fetch live models
|
| 92 |
+
live_models = fetch_top_models(unique_tasks, license_filter=license_filter, top_n=5)
|
| 93 |
+
model_table = format_model_table(live_models)
|
| 94 |
+
|
| 95 |
+
# Deployment path
|
| 96 |
+
if data_sensitivity == "Strict: prefer on-prem / VPC only":
|
| 97 |
+
deploy_path = "π **Private Self-Hosted** - Run top open-source models above via Ollama or vLLM on your own infra."
|
| 98 |
+
elif volume == "100,000+":
|
| 99 |
+
deploy_path = "π° **Cost-Optimized Scale** - Use provisioned throughput for closed models, or self-host on GPU clusters."
|
| 100 |
+
else:
|
| 101 |
+
deploy_path = "β‘ **Serverless API** - Closed models: OpenAI/Anthropic/Google APIs. Open-source: HF Inference Endpoints."
|
| 102 |
+
|
| 103 |
+
# Smart tips
|
| 104 |
+
tips = []
|
| 105 |
+
if any(d in ["Healthcare", "Finance", "Legal"] for d in domains):
|
| 106 |
+
tips.append("π **Zero Data Retention (ZDR)** - For regulated domains, enable ZDR on OpenAI/Anthropic/Google or use on-prem.")
|
| 107 |
+
if latency == "< 500 ms (Instant)":
|
| 108 |
+
tips.append("β‘ **Pick a smaller distilled variant** - Sort by 'likes' and look for 7B/8B versions of the top model.")
|
| 109 |
+
if context_size == "32K - 200K tokens (Long)":
|
| 110 |
+
tips.append("π **Add a RAG layer** - Even for long-context models, pair with Pinecone/Weaviate/pgvector for accuracy.")
|
| 111 |
+
if "Style fine-tuning" in customization:
|
| 112 |
+
tips.append("π¨ **Fine-tune with QLoRA** - Take the top model from the table above and fine-tune on 1k-5k domain examples.")
|
| 113 |
+
if "RAG + Tool Calling" in customization:
|
| 114 |
+
tips.append("π§ **Enable Tool Calling** - Most top models support function calling / tool use. Check the model card for schema.")
|
| 115 |
+
|
| 116 |
+
if not tips:
|
| 117 |
+
tips.append("β¨ Start with the #1 model in the table above and iterate. A great system prompt gets you 80% of the way.")
|
| 118 |
+
|
| 119 |
+
tips_text = (NL + "- ").join(tips)
|
| 120 |
+
|
| 121 |
+
how_to = (
|
| 122 |
+
"### π Your 3-Step Rollout Guide" + NL +
|
| 123 |
+
"1. **Sandbox (Week 1):** Clone the top 3 models from the table above. Run 50-100 real queries from your dataset." + NL +
|
| 124 |
+
"2. **Evaluate (Week 2):** Score on accuracy, latency, and cost per 1K tokens. Eliminate bottom performers." + NL +
|
| 125 |
+
"3. **Deploy (Week 3):** Integrate the winner via API or self-hosted endpoint. Set up monitoring with LangSmith or Helicone." + NL
|
| 126 |
+
)
|
| 127 |
+
|
| 128 |
+
tasks_label = ", ".join(f"`{t}`" for t in unique_tasks)
|
| 129 |
+
license_label = f"license: `{license_filter}`" if license_filter else "all licenses"
|
| 130 |
+
|
| 131 |
+
summary = (
|
| 132 |
+
"## π Your Live AI Model Strategy" + NL + NL +
|
| 133 |
+
"### π¦ Top Models on HuggingFace Hub Right Now" + NL +
|
| 134 |
+
f"*Live from HF Hub API | Tasks: {tasks_label} | Filter: {license_label} | Sorted by downloads*" + NL + NL +
|
| 135 |
+
model_table + NL + NL +
|
| 136 |
+
"### πΊοΈ Best Deployment Path" + NL +
|
| 137 |
+
deploy_path + NL + NL +
|
| 138 |
+
"### π‘ Pro-Tips for Your Use Case" + NL +
|
| 139 |
+
"- " + tips_text + NL + NL +
|
| 140 |
+
how_to
|
| 141 |
+
)
|
| 142 |
+
|
| 143 |
+
return summary, gr.update(visible=True)
|
| 144 |
+
|
| 145 |
+
def handle_lead(name, email, company, infra):
|
| 146 |
+
if not email:
|
| 147 |
+
return "Please provide an email to receive your architecture PDF."
|
| 148 |
+
return f"β
Thanks {name}! We've queued your custom architecture PDF for {company}. Check your inbox at {email} shortly."
|
| 149 |
+
|
| 150 |
+
with gr.Blocks(theme=gr.themes.Soft(primary_hue="orange", secondary_hue="slate"), title="AI Model Picker | AnkTechsol") as demo:
|
| 151 |
+
gr.Markdown("# π AI Model Selection Wizard")
|
| 152 |
+
gr.Markdown("**Pick the perfect AI brain for your use case.** This tool queries the HuggingFace Hub live and returns the top trending models for your exact task - no hardcoded lists. By [AnkTechsol](https://anktechsol.com).")
|
| 153 |
+
|
| 154 |
+
with gr.Row():
|
| 155 |
+
with gr.Column(scale=1):
|
| 156 |
+
gr.Markdown("### π Step 1: Describe Your Task")
|
| 157 |
+
modality = gr.CheckboxGroup(label="What inputs are you working with?", choices=["Text in -> text out", "Images in (docs, UI, scans)", "Audio in (speech)", "Structured data (tables, logs)", "Code"])
|
| 158 |
+
outputs = gr.CheckboxGroup(label="What output do you need?", choices=["Natural language answer / summary", "Classification / tagging", "Field extraction from text/PDF", "Content generation (copy, emails)", "Scoring / ranking / decision"])
|
| 159 |
+
domains = gr.CheckboxGroup(label="Your Industry / Domain", choices=["General / consumer", "Ecommerce / SaaS", "Finance", "Healthcare", "Legal", "Internal enterprise knowledge"])
|
| 160 |
+
|
| 161 |
+
with gr.Column(scale=1):
|
| 162 |
+
gr.Markdown("### βοΈ Step 2: Set Your Constraints")
|
| 163 |
+
data_sensitivity = gr.Radio(label="Data Privacy Requirements", choices=["Standard SaaS API is fine", "Must stay in a specific cloud region", "Strict: prefer on-prem / VPC only"], value="Standard SaaS API is fine")
|
| 164 |
+
volume = gr.Radio(label="Expected Daily Request Volume", choices=["< 1,000", "1,000 - 100,000", "100,000+"], value="< 1,000")
|
| 165 |
+
latency = gr.Radio(label="Latency Requirement", choices=["< 500 ms (Instant)", "0.5 - 5 s (Standard)", "> 5 s (Batch)"], value="0.5 - 5 s (Standard)")
|
| 166 |
+
context_size = gr.Radio(label="Max Context Window Needed", choices=["< 4K tokens (Short)", "4K - 32K tokens (Medium)", "32K - 200K tokens (Long)"], value="4K - 32K tokens (Medium)")
|
| 167 |
+
customization = gr.CheckboxGroup(label="Customization Needs", choices=["Prompt engineering only", "Style fine-tuning", "RAG + Tool Calling"])
|
| 168 |
+
|
| 169 |
+
gr.Markdown("### π What you'll get:")
|
| 170 |
+
gr.Markdown("- **Top 5 Live Models** from HF Hub matched to your task" + NL + "- **Optimized Deployment Path** (Cloud vs On-Prem)" + NL + "- **3-Week Implementation Roadmap**" + NL + "- **Tailored Cost & Latency Pro-Tips**")
|
| 171 |
+
|
| 172 |
+
submit_btn = gr.Button("β¨ Fetch Live Models and Generate My Strategy", variant="primary", size="lg")
|
| 173 |
+
gr.Markdown("> π *Querying HuggingFace Hub live - may take 5-10 seconds. Please wait after clicking.*")
|
| 174 |
+
|
| 175 |
+
gr.Markdown("---")
|
| 176 |
+
|
| 177 |
+
output_md = gr.Markdown(label="Your Live AI Strategy")
|
| 178 |
+
|
| 179 |
+
with gr.Column(visible=False) as lead_section:
|
| 180 |
+
gr.Markdown("---")
|
| 181 |
+
gr.Markdown("### π§ Get Your Custom Architecture PDF")
|
| 182 |
+
gr.Markdown("We'll take your results above and generate a detailed 1-page architecture diagram and cost estimate for your stack.")
|
| 183 |
+
with gr.Row():
|
| 184 |
+
name = gr.Textbox(label="Name", placeholder="Anuj Karn")
|
| 185 |
+
email = gr.Textbox(label="Work Email", placeholder="anuj@anktechsol.com")
|
| 186 |
+
with gr.Row():
|
| 187 |
+
company = gr.Textbox(label="Company / Project", placeholder="AnkTechsol")
|
| 188 |
+
infra = gr.Dropdown(label="Current Infra", choices=["AWS", "GCP", "Azure", "On-Prem", "Other/None"], value="AWS")
|
| 189 |
+
|
| 190 |
+
lead_btn = gr.Button("π₯ Send Me My Architecture PDF", variant="primary")
|
| 191 |
+
lead_status = gr.Markdown("")
|
| 192 |
+
|
| 193 |
+
gr.Markdown("### βοΈ Ready to build?")
|
| 194 |
+
gr.Markdown("Contact us at [**colab@anktechsol.com**](mailto:colab@anktechsol.com) to review these results with our architecture team and map your production roadmap.")
|
| 195 |
+
|
| 196 |
+
submit_btn.click(
|
| 197 |
+
fn=recommend_model,
|
| 198 |
+
inputs=[modality, outputs, domains, data_sensitivity, volume, latency, context_size, customization],
|
| 199 |
+
outputs=[output_md, lead_section]
|
| 200 |
+
)
|
| 201 |
+
|
| 202 |
+
lead_btn.click(
|
| 203 |
+
fn=handle_lead,
|
| 204 |
+
inputs=[name, email, company, infra],
|
| 205 |
+
outputs=lead_status
|
| 206 |
+
)
|
| 207 |
+
|
| 208 |
+
gr.Markdown("---")
|
| 209 |
+
gr.Markdown("### π οΈ Why Teams Trust AnkTechsol")
|
| 210 |
+
gr.Markdown("We help startups and enterprises go from AI confusion to production-grade AI systems. Fine-tuning, RAG pipelines, GPU inferencing as a service - we deliver.")
|
| 211 |
+
gr.Markdown("**[Visit anktechsol.com](https://anktechsol.com) | [LinkedIn](https://www.linkedin.com/company/anktechsol)**")
|
| 212 |
+
|
| 213 |
+
if __name__ == "__main__":
|
| 214 |
+
demo.launch()
|