File size: 7,247 Bytes
975da6d 8bdee2c 975da6d 0119bc3 8bdee2c 975da6d 98115c9 975da6d 0146f4c 0119bc3 0146f4c 975da6d 0119bc3 975da6d 0119bc3 975da6d 584fbba 692cbd8 584fbba 0cc54a6 584fbba 692cbd8 0cc54a6 584fbba 692cbd8 0cc54a6 692cbd8 0cc54a6 692cbd8 0cc54a6 692cbd8 0cc54a6 692cbd8 0cc54a6 692cbd8 0cc54a6 692cbd8 0cc54a6 692cbd8 0cc54a6 692cbd8 0cc54a6 692cbd8 0cc54a6 692cbd8 0cc54a6 584fbba 0cc54a6 692cbd8 0cc54a6 692cbd8 584fbba 975da6d 692cbd8 0cc54a6 584fbba 0cc54a6 584fbba 0cc54a6 975da6d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | import gradio as gr
import spaces
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
# --- Configuration ---
MODEL_ID = "aslanconfig/tech-advisor-nemotron-4b"
SYSTEM_PROMPT = """/no_think
You are Tech Advisor, an expert on AWS cloud services with deep knowledge of AWS DevOps Agent.
You have comprehensive knowledge of AWS DevOps Agent including:
- What it is and how it works (Agent Spaces, topology, dual-console architecture)
- Key features: autonomous incident response, proactive prevention, on-demand SRE tasks
- Integrations: CloudWatch, Datadog, Dynatrace, New Relic, Splunk, Grafana, PagerDuty, GitHub, GitLab, Azure DevOps, ServiceNow, Slack
- GA features: Azure/on-prem support, Triage Agent, Learned/Custom Skills, Code Indexing, Private Connections
- Pricing: $0.0083 per agent-second, free trial details, AWS Support credits
- Getting started: Agent Spaces, connecting tools, running investigations
- Security: encryption, customer managed keys, IdP integration, CloudTrail auditing
- Available regions: US East, US West, Frankfurt, Ireland, Sydney, Tokyo
Be concise and structured. Use bullet points where appropriate. Provide accurate, detailed answers."""
# --- Load model ---
tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
device = "cuda" if torch.cuda.is_available() else "cpu"
model = AutoModelForCausalLM.from_pretrained(
MODEL_ID,
torch_dtype=torch.bfloat16,
).to(device).eval()
@spaces.GPU
def respond(message: str, history: list[dict]) -> str:
"""Generate a response using the fine-tuned Llama-3.1-Nemotron-Nano-4B."""
messages = [{"role": "system", "content": SYSTEM_PROMPT}]
for msg in history:
if msg.get("role") and msg.get("content"):
messages.append({"role": msg["role"], "content": str(msg["content"])})
messages.append({"role": "user", "content": message})
input_ids = tokenizer.apply_chat_template(
messages, return_tensors="pt", add_generation_prompt=True, tokenize=True
)
if hasattr(input_ids, "input_ids"):
input_ids = input_ids.input_ids
if not isinstance(input_ids, torch.Tensor):
input_ids = torch.tensor([input_ids])
input_ids = input_ids.to(model.device)
with torch.no_grad():
generated_ids = model.generate(
input_ids,
max_new_tokens=2048,
do_sample=True,
temperature=0.3,
top_p=0.9,
eos_token_id=tokenizer.eos_token_id,
)
output_text = tokenizer.decode(
generated_ids[0][input_ids.shape[1]:],
skip_special_tokens=True,
)
return output_text
CSS = """
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&display=swap');
.gradio-container {
max-width: 900px !important;
margin: auto !important;
background: #0d1117 !important;
font-family: 'JetBrains Mono', monospace !important;
min-height: 100vh;
}
footer { display: none !important; }
.terminal-header {
background: #161b22;
border: 1px solid #30363d;
border-radius: 8px;
padding: 0;
margin-bottom: 20px;
overflow: hidden;
box-shadow: 0 8px 32px rgba(0, 255, 65, 0.1);
}
.terminal-bar {
background: #21262d;
padding: 8px 14px;
display: flex;
align-items: center;
gap: 8px;
border-bottom: 1px solid #30363d;
}
.terminal-dot {
width: 12px; height: 12px; border-radius: 50%;
}
.dot-red { background: #ff5f56; }
.dot-yellow { background: #ffbd2e; }
.dot-green { background: #27c93f; }
.terminal-title {
color: #8b949e;
font-size: 0.8em;
margin-left: 10px;
font-family: 'JetBrains Mono', monospace;
}
.terminal-body {
padding: 20px 24px;
color: #c9d1d9;
font-family: 'JetBrains Mono', monospace;
font-size: 0.9em;
line-height: 1.8;
}
.terminal-body .prompt { color: #27c93f; }
.terminal-body .cmd { color: #f0f6fc; font-weight: 700; }
.terminal-body .output { color: #8b949e; }
.terminal-body .highlight { color: #ff7b72; }
.terminal-body .cyan { color: #79c0ff; }
.terminal-body .yellow { color: #e3b341; }
.stats-row {
display: flex;
gap: 12px;
margin-top: 16px;
flex-wrap: wrap;
}
.stat-chip {
background: #21262d;
border: 1px solid #30363d;
border-radius: 6px;
padding: 6px 12px;
font-size: 0.8em;
color: #c9d1d9;
font-family: 'JetBrains Mono', monospace;
}
.stat-chip .val { color: #27c93f; font-weight: 700; }
.footer-bar {
text-align: center;
padding: 14px;
margin-top: 15px;
background: #161b22;
border: 1px solid #30363d;
border-radius: 8px;
color: #8b949e;
font-size: 0.8em;
font-family: 'JetBrains Mono', monospace;
}
.footer-bar a { color: #27c93f; text-decoration: none; }
.footer-bar a:hover { text-decoration: underline; }
"""
HEADER = """
<div class="terminal-header">
<div class="terminal-bar">
<span class="terminal-dot dot-red"></span>
<span class="terminal-dot dot-yellow"></span>
<span class="terminal-dot dot-green"></span>
<span class="terminal-title">local-tech-advisor v1.0 — bash</span>
</div>
<div class="terminal-body">
<span class="prompt">$</span> <span class="cmd">./local-tech-advisor --start</span><br>
<span class="output">[INFO] Loading model: <span class="cyan">nemotron-nano-4b</span> (fine-tuned)</span><br>
<span class="output">[INFO] Training cost: <span class="highlight">$2.03</span> | Training time: <span class="highlight">35 min</span></span><br>
<span class="output">[INFO] API calls needed: <span class="yellow">none. ever.</span></span><br>
<span class="output">[INFO] Status: <span class="cyan">ready</span> — ask me anything about AWS DevOps Agent</span><br>
<span class="prompt">$</span> <span class="cmd blink">_</span>
<div class="stats-row">
<span class="stat-chip"><span class="val">4B</span> params</span>
<span class="stat-chip"><span class="val">66</span> docs</span>
<span class="stat-chip"><span class="val">1,230</span> Q&A pairs</span>
<span class="stat-chip"><span class="val">$0</span> per query</span>
<span class="stat-chip"><span class="val">0</span> APIs called</span>
</div>
</div>
</div>
"""
FOOTER = """
<div class="footer-bar">
<span class="prompt">$</span> echo "Built for Build Small Hackathon" |
model: <a href="https://huggingface.co/aslanconfig/tech-advisor-nemotron-4b" target="_blank">aslanconfig/tech-advisor-nemotron-4b</a> |
sponsor: nvidia | track: backyard
</div>
"""
# --- Gradio UI ---
with gr.Blocks(css=CSS, title="Local Tech Advisor") as demo:
gr.HTML(HEADER)
gr.ChatInterface(
fn=respond,
examples=[
"What is AWS DevOps Agent and how does it work?",
"How much does AWS DevOps Agent cost?",
"What observability tools does it integrate with?",
"How do I create an Agent Space?",
"What security features does AWS DevOps Agent provide?",
"What regions is AWS DevOps Agent available in?",
],
cache_examples=False,
)
gr.HTML(FOOTER)
if __name__ == "__main__":
demo.launch()
|