Spaces:
Sleeping
Sleeping
changed LLM again
Browse files
app.py
CHANGED
|
@@ -357,7 +357,7 @@ class CVEDashboard:
|
|
| 357 |
|
| 358 |
def generate_tailored_summary(cve_description: str, audience: str, hf_token: Optional[str] = None, max_retries: int = 2) -> str:
|
| 359 |
"""
|
| 360 |
-
Generates a tailored CVE summary using
|
| 361 |
|
| 362 |
Args:
|
| 363 |
cve_description: The original CVE description
|
|
@@ -380,20 +380,19 @@ def generate_tailored_summary(cve_description: str, audience: str, hf_token: Opt
|
|
| 380 |
if audience not in AUDIENCE_PROFILES:
|
| 381 |
return f"❌ Unknown audience: {audience}"
|
| 382 |
|
| 383 |
-
#
|
| 384 |
models = [
|
| 385 |
-
"
|
| 386 |
-
"mistralai/Mistral-7B-Instruct-v0.3" # Fallback to original
|
| 387 |
]
|
| 388 |
|
| 389 |
headers = {"Authorization": f"Bearer {token}"}
|
| 390 |
profile = AUDIENCE_PROFILES[audience]
|
| 391 |
|
| 392 |
-
#
|
| 393 |
-
|
| 394 |
-
|
| 395 |
-
|
| 396 |
-
|
| 397 |
**Target Audience:** {audience}
|
| 398 |
**Focus:** {profile['focus']}
|
| 399 |
**Tone:** {profile['tone']}
|
|
@@ -401,65 +400,38 @@ def generate_tailored_summary(cve_description: str, audience: str, hf_token: Opt
|
|
| 401 |
**CVE Description:**
|
| 402 |
{cve_description[:1200]}
|
| 403 |
Provide a concise, actionable summary (2-3 sentences) highlighting what matters most to this audience. Focus on practical implications and next steps."""
|
| 404 |
-
|
| 405 |
-
|
|
|
|
| 406 |
|
| 407 |
for model in models:
|
| 408 |
api_url = f"https://api-inference.huggingface.co/models/{model}"
|
| 409 |
|
| 410 |
-
|
| 411 |
-
|
| 412 |
-
|
| 413 |
-
"
|
| 414 |
-
|
| 415 |
-
|
| 416 |
-
|
| 417 |
-
|
| 418 |
-
|
| 419 |
-
}
|
| 420 |
-
else:
|
| 421 |
-
# Fallback to Mistral format
|
| 422 |
-
prompt = f"""<s>[INST] You are an expert cybersecurity analyst. Rewrite the following CVE description for a {audience}.
|
| 423 |
-
**Focus:** {profile['focus']}
|
| 424 |
-
**Tone:** {profile['tone']}
|
| 425 |
-
CVE: {cve_description[:1000]}
|
| 426 |
-
Provide a 2-3 sentence summary highlighting what matters most to this audience: [/INST]"""
|
| 427 |
-
|
| 428 |
-
payload = {
|
| 429 |
-
"inputs": prompt,
|
| 430 |
-
"parameters": {
|
| 431 |
-
"max_new_tokens": 150,
|
| 432 |
-
"temperature": 0.5,
|
| 433 |
-
"top_p": 0.9,
|
| 434 |
-
"do_sample": True,
|
| 435 |
-
"return_full_text": False,
|
| 436 |
-
"stop": ["\n\n"]
|
| 437 |
-
}
|
| 438 |
}
|
|
|
|
| 439 |
|
| 440 |
for attempt in range(max_retries):
|
| 441 |
try:
|
| 442 |
logger.info(f"Generating summary with {model} (attempt {attempt + 1})")
|
| 443 |
|
| 444 |
response = requests.post(api_url, headers=headers, json=payload, timeout=45)
|
| 445 |
-
|
| 446 |
if response.status_code == 200:
|
| 447 |
try:
|
| 448 |
result = response.json()
|
| 449 |
|
| 450 |
-
#
|
| 451 |
summary = ""
|
| 452 |
-
if
|
| 453 |
-
|
| 454 |
-
if isinstance(result, list) and len(result) > 0:
|
| 455 |
-
if "generated_text" in result[0]:
|
| 456 |
-
summary = result[0]["generated_text"]
|
| 457 |
-
elif "choices" in result[0] and len(result[0]["choices"]) > 0:
|
| 458 |
-
summary = result[0]["choices"][0].get("message", {}).get("content", "")
|
| 459 |
-
else:
|
| 460 |
-
# Mistral response format
|
| 461 |
-
if isinstance(result, list) and len(result) > 0:
|
| 462 |
-
summary = result[0].get('generated_text', '').strip()
|
| 463 |
|
| 464 |
if summary and len(summary) > 20:
|
| 465 |
logger.info(f"Successfully generated summary with {model}")
|
|
@@ -616,8 +588,7 @@ def create_interface():
|
|
| 616 |
- Search CVEs by date range and keywords
|
| 617 |
- Filter by severity levels
|
| 618 |
- Visualize CVE distributions and trends
|
| 619 |
-
-
|
| 620 |
-
- **NEW:** AI-powered audience-specific summaries using multiple LLMs
|
| 621 |
|
| 622 |
**Supported Audiences:**
|
| 623 |
- **Cybersecurity Professional:** Focus on threats, attack vectors, and mitigation
|
|
@@ -629,11 +600,12 @@ def create_interface():
|
|
| 629 |
|
| 630 |
**Data Source:** [NIST NVD API](https://nvd.nist.gov/developers/vulnerabilities)
|
| 631 |
|
| 632 |
-
**AI
|
|
|
|
|
|
|
| 633 |
|
| 634 |
**Performance Optimizations:**
|
| 635 |
- Shorter timeouts for faster failure detection
|
| 636 |
-
- Multiple model fallback for reliability
|
| 637 |
- Optimized prompts for quicker responses
|
| 638 |
|
| 639 |
**Rate Limits:**
|
|
|
|
| 357 |
|
| 358 |
def generate_tailored_summary(cve_description: str, audience: str, hf_token: Optional[str] = None, max_retries: int = 2) -> str:
|
| 359 |
"""
|
| 360 |
+
Generates a tailored CVE summary using SmolLM3-3B via HuggingFace Inference API.
|
| 361 |
|
| 362 |
Args:
|
| 363 |
cve_description: The original CVE description
|
|
|
|
| 380 |
if audience not in AUDIENCE_PROFILES:
|
| 381 |
return f"❌ Unknown audience: {audience}"
|
| 382 |
|
| 383 |
+
# Define the model to use
|
| 384 |
models = [
|
| 385 |
+
"HuggingFaceTB/SmolLM3-3B",
|
|
|
|
| 386 |
]
|
| 387 |
|
| 388 |
headers = {"Authorization": f"Bearer {token}"}
|
| 389 |
profile = AUDIENCE_PROFILES[audience]
|
| 390 |
|
| 391 |
+
# SmolLM3 uses a specific chat template format.
|
| 392 |
+
# Build the prompt string manually based on its tokenizer_config.json.
|
| 393 |
+
# The system prompt includes /no_think to get a direct answer without a reasoning trace.
|
| 394 |
+
system_prompt = "You are an expert cybersecurity analyst. /no_think"
|
| 395 |
+
user_prompt = f"""Rewrite this CVE description for a {audience}.
|
| 396 |
**Target Audience:** {audience}
|
| 397 |
**Focus:** {profile['focus']}
|
| 398 |
**Tone:** {profile['tone']}
|
|
|
|
| 400 |
**CVE Description:**
|
| 401 |
{cve_description[:1200]}
|
| 402 |
Provide a concise, actionable summary (2-3 sentences) highlighting what matters most to this audience. Focus on practical implications and next steps."""
|
| 403 |
+
|
| 404 |
+
# Manually apply the chat template
|
| 405 |
+
prompt = f"### System:\n{system_prompt}\n### User:\n{user_prompt}\n### Assistant:\n"
|
| 406 |
|
| 407 |
for model in models:
|
| 408 |
api_url = f"https://api-inference.huggingface.co/models/{model}"
|
| 409 |
|
| 410 |
+
payload = {
|
| 411 |
+
"inputs": prompt,
|
| 412 |
+
"parameters": {
|
| 413 |
+
"max_new_tokens": 200,
|
| 414 |
+
"temperature": 0.6, # Recommended
|
| 415 |
+
"top_p": 0.95, # Recommended
|
| 416 |
+
"do_sample": True,
|
| 417 |
+
"return_full_text": False,
|
| 418 |
+
"stop": ["\n###", "<|endoftext|>"] # Stop sequences
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 419 |
}
|
| 420 |
+
}
|
| 421 |
|
| 422 |
for attempt in range(max_retries):
|
| 423 |
try:
|
| 424 |
logger.info(f"Generating summary with {model} (attempt {attempt + 1})")
|
| 425 |
|
| 426 |
response = requests.post(api_url, headers=headers, json=payload, timeout=45)
|
|
|
|
| 427 |
if response.status_code == 200:
|
| 428 |
try:
|
| 429 |
result = response.json()
|
| 430 |
|
| 431 |
+
# Standard response format for this payload type
|
| 432 |
summary = ""
|
| 433 |
+
if isinstance(result, list) and len(result) > 0:
|
| 434 |
+
summary = result[0].get('generated_text', '').strip()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 435 |
|
| 436 |
if summary and len(summary) > 20:
|
| 437 |
logger.info(f"Successfully generated summary with {model}")
|
|
|
|
| 588 |
- Search CVEs by date range and keywords
|
| 589 |
- Filter by severity levels
|
| 590 |
- Visualize CVE distributions and trends
|
| 591 |
+
- AI-powered audience-specific summaries using the SmolLM3-3B model.
|
|
|
|
| 592 |
|
| 593 |
**Supported Audiences:**
|
| 594 |
- **Cybersecurity Professional:** Focus on threats, attack vectors, and mitigation
|
|
|
|
| 600 |
|
| 601 |
**Data Source:** [NIST NVD API](https://nvd.nist.gov/developers/vulnerabilities)
|
| 602 |
|
| 603 |
+
**AI Model:** [HuggingFaceTB/SmolLM3-3B](https://huggingface.co/HuggingFaceTB/SmolLM3-3B)
|
| 604 |
+
|
| 605 |
+
**Disclaimer:** Generated content may be inaccurate or false.
|
| 606 |
|
| 607 |
**Performance Optimizations:**
|
| 608 |
- Shorter timeouts for faster failure detection
|
|
|
|
| 609 |
- Optimized prompts for quicker responses
|
| 610 |
|
| 611 |
**Rate Limits:**
|