Spaces:
Sleeping
Sleeping
File size: 12,234 Bytes
75164b7 | 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 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 | """
Code evaluation for all three Groq models
Tests Python and JavaScript code generation
Uses LLM Testing Suite with CCE formula from paper
"""
from groq import Groq
import json
import re
import sys
import os
from datetime import datetime
# Add parent directory to path to import llm_testing_suite
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from llm_testing_suite import LLMTestSuite
# API Key
GROQ_API_KEY = "your-groq-api-key-here"
# Models to test
MODELS = {
"GPT-OSS-20B": "openai/gpt-oss-20b",
"Llama-3.3-70B": "llama-3.3-70b-versatile",
"Qwen3-32B": "qwen/qwen3-32b"
}
client = Groq(api_key=GROQ_API_KEY)
def create_llm_function(model_name):
"""Create LLM function for specific model with Qwen-safe parameters"""
def llm_func(prompt: str, max_tokens=600, temperature=0.3) -> str:
# For Qwen models, use non-thinking mode parameters
is_qwen = "qwen" in model_name.lower()
# Enhanced system message to prevent <think> tags
system_content = """You are an expert programmer. Generate ONLY clean,
executable code without any explanations, reasoning, or commentary.
Do not use <think> tags or any surrounding text. Return pure code only."""
# Enhanced prompt to emphasize code-only output
enhanced_prompt = f"{prompt}\n\nIMPORTANT: Return ONLY the code, no explanations or reasoning."
messages = [
{"role": "system", "content": system_content},
{"role": "user", "content": enhanced_prompt}
]
try:
# Parameters based on Qwen best practices
api_params = {
"model": model_name,
"messages": messages,
"max_tokens": max_tokens,
}
if is_qwen:
# Non-thinking mode for Qwen (general dialogue settings)
# Note: Groq API doesn't support top_k or min_p
api_params.update({
"temperature": 0.7,
"top_p": 0.8,
})
else:
# Standard parameters for other models
api_params.update({
"temperature": temperature,
"top_p": 0.8,
})
response = client.chat.completions.create(**api_params)
raw_response = response.choices[0].message.content.strip()
# Debug: Print raw response for debugging
if is_qwen:
print(f" [DEBUG] Qwen raw response ({len(raw_response)} chars):")
print(f" {raw_response[:500]}")
return raw_response
except Exception as e:
print(f" Error: {e}")
return ""
return llm_func
def extract_code_block(response: str, language: str = "python") -> str:
"""Extract code from markdown code blocks and remove reasoning text"""
original_response = response
# FIRST: Aggressively remove <think> tags and their content
# Use multiple patterns to catch variations
response = re.sub(r'<think>.*?</think>', '', response, flags=re.DOTALL | re.IGNORECASE)
response = re.sub(r'<thinking>.*?</thinking>', '', response, flags=re.DOTALL | re.IGNORECASE)
# Remove any remaining think tags (unclosed or malformed)
response = re.sub(r'</?think.*?>', '', response, flags=re.IGNORECASE)
response = re.sub(r'</?thinking.*?>', '', response, flags=re.IGNORECASE)
# Try to extract from markdown code blocks with language
pattern = rf"```{language}\n(.*?)\n```"
match = re.search(pattern, response, re.DOTALL | re.IGNORECASE)
if match:
return match.group(1).strip()
# Try to extract from generic markdown code blocks
pattern = r"```\n(.*?)\n```"
match = re.search(pattern, response, re.DOTALL)
if match:
return match.group(1).strip()
# Try just ``` with any language
pattern = r"```\w*\n(.*?)\n```"
match = re.search(pattern, response, re.DOTALL)
if match:
return match.group(1).strip()
# Special handling: Extract only valid Python code lines
lines = response.split('\n')
code_lines = []
in_code_block = False
for line in lines:
stripped = line.strip()
# Skip empty lines at the start
if not code_lines and not stripped:
continue
# Skip obvious reasoning/explanation lines
lower_line = line.lower()
if any(marker in lower_line for marker in [
'okay,', 'let me', 'i need to', 'first,', 'to solve', 'the user',
'then,', 'but need', 'make sure', 'wait,', 'hmm,', 'so,',
'starting with', 'in the main', 'oh right', 'like if'
]):
continue
# Check if line looks like valid Python code
is_code_like = (
stripped.startswith(('def ', 'class ', 'import ', 'from ', 'if ', 'for ', 'while ',
'try:', 'except', 'return ', 'print(', '@')) or
stripped.startswith('if __name__') or
(stripped and not stripped[0].isupper() and '=' in stripped) or # assignment
(in_code_block and (stripped.startswith((' ', '\t')) or not stripped)) # indented or blank
)
# Start collecting code when we find a def, class, import, or if __name__
if stripped.startswith(('def ', 'class ', 'import ', 'from ', 'if __name__')):
in_code_block = True
code_lines.append(line)
elif in_code_block:
# Continue collecting if it looks like code
if is_code_like or not stripped:
code_lines.append(line)
elif stripped and (stripped[0].isupper() or ':' not in line):
# Stop if we hit explanatory text (starts with capital, no colons)
# But allow docstrings
if '"""' not in line and "'''" not in line:
break
else:
code_lines.append(line)
else:
code_lines.append(line)
if code_lines:
# Clean up trailing empty lines and explanatory text
while code_lines and not code_lines[-1].strip():
code_lines.pop()
# Remove any trailing lines that look like explanations
while code_lines:
last_line = code_lines[-1].strip().lower()
if any(marker in last_line for marker in ['but need', 'make sure', 'wait', 'note:']):
code_lines.pop()
else:
break
return '\n'.join(code_lines).strip()
# Last resort: return cleaned response
response = re.sub(r'^(Here\'s|Here is|This is).*?:\s*', '', response, flags=re.IGNORECASE)
return response.strip()
print("="*80)
print("CODE EVALUATION FOR THREE GROQ MODELS")
print("Using LLM Testing Suite with CCE Formula from Paper")
print("="*80)
print(f"Models: {', '.join(MODELS.keys())}")
print(f"Date: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print("="*80)
# Code generation prompt
PYTHON_PROMPT = """Write a Python program that:
1. Defines a function called 'add_numbers' that takes two integers and returns their sum
2. Includes a docstring for the function
3. Has a main block that reads two space-separated integers from stdin and prints the result
4. The output should be just the number, nothing else
Example: if input is "2 3", output should be "5" """
PYTHON_TEST_CASES = [
{"input": "2 3\n", "expected_output": "5"},
{"input": "-1 4\n", "expected_output": "3"},
{"input": "0 0\n", "expected_output": "0"},
{"input": "10 -5\n", "expected_output": "5"}
]
# Reference implementation for semantic comparison
REFERENCE_CODE = '''def add_numbers(a, b):
"""Add two numbers and return the result."""
return a + b
if __name__ == "__main__":
numbers = input().split()
a, b = int(numbers[0]), int(numbers[1])
print(add_numbers(a, b))
'''
all_results = {}
for model_display_name, model_id in MODELS.items():
print(f"\n{'='*80}")
print(f"EVALUATING: {model_display_name} ({model_id})")
print(f"{'='*80}")
# Create LLM function for this model
llm_func = create_llm_function(model_id)
# Initialize testing suite
suite = LLMTestSuite(llm_func=llm_func)
print("\nGenerating Python code...")
code_response = llm_func(PYTHON_PROMPT, max_tokens=500, temperature=0.3)
generated_code = extract_code_block(code_response, "python")
print(f"Generated {len(generated_code)} characters of code")
print("\nCode preview:")
print("-" * 40)
print(generated_code[:300] + ("..." if len(generated_code) > 300 else ""))
print("-" * 40)
# Run comprehensive evaluation using the suite
print("\nRunning comprehensive code evaluation...")
result = suite.comprehensive_code_evaluation(
prompt=PYTHON_PROMPT,
code_response=generated_code,
reference_code=REFERENCE_CODE,
test_cases=PYTHON_TEST_CASES,
language="python",
return_type="dict"
)
# Display results
print(f"\n--- EVALUATION RESULTS ---")
print(f"Syntax Valid (SV): {result['syntax_valid']} ({1.0 if result['syntax_valid'] else 0.0})")
print(f"Execution Pass Rate (EPR): {result.get('pass_rate', 1.0):.3f}")
print(f"Code Quality Score (CQS): {result['quality_score']}/100 ({result['quality_score']/100:.3f})")
print(f"Security Risk Score (SRS): {result.get('srs', 0.0):.3f}")
print(f"Security Score (1-SRS): {1 - result.get('srs', 0.0):.3f}")
print(f"Semantic Correctness (SCC): {result.get('semantic_similarity', 1.0):.3f}")
print(f"\n--- CCE BREAKDOWN ---")
breakdown = result.get('metrics_breakdown', {})
print(f"α*SV (0.15 × {breakdown.get('sv', 0):.3f}) = {0.15 * breakdown.get('sv', 0):.4f}")
print(f"β*EPR (0.35 × {breakdown.get('epr', 0):.3f}) = {0.35 * breakdown.get('epr', 0):.4f}")
print(f"γ*CQS (0.20 × {breakdown.get('cqs', 0):.3f}) = {0.20 * breakdown.get('cqs', 0):.4f}")
print(f"δ*(1-SRS) (0.15 × {breakdown.get('security_score', 0):.3f}) = {0.15 * breakdown.get('security_score', 0):.4f}")
print(f"ϵ*SCC (0.15 × {breakdown.get('scc', 0):.3f}) = {0.15 * breakdown.get('scc', 0):.4f}")
print(f"\nCCE Score: {result['cce_score']:.4f}")
print(f"Overall Score: {result['overall_score']:.2f}/100")
all_results[model_display_name] = {
"model_name": model_display_name,
"model_id": model_id,
"python": {
"syntax_valid": result['syntax_valid'],
"pass_rate": result.get('pass_rate', 1.0),
"quality_score": result['quality_score'],
"srs": result.get('srs', 0.0),
"security_score": 1 - result.get('srs', 0.0),
"semantic_similarity": result.get('semantic_similarity', 1.0),
"cce_score": result['cce_score'],
"overall_score": result['overall_score'],
"metrics_breakdown": result.get('metrics_breakdown', {}),
"generated_code": generated_code
}
}
# Save results
output_file = "code_evaluation_results.json"
with open(output_file, 'w') as f:
json.dump(all_results, f, indent=2)
print(f"\n{'='*80}")
print(f"CODE EVALUATION COMPLETE")
print(f"Results saved to {output_file}")
print(f"{'='*80}")
# Summary table
print("\n\nSUMMARY TABLE - CCE SCORES:")
print("-" * 120)
print(f"{'Model':<20} {'SV':<8} {'EPR':<8} {'CQS':<8} {'1-SRS':<8} {'SCC':<8} {'CCE':<10} {'Overall':<12}")
print("-" * 120)
for model_name, results in all_results.items():
py = results["python"]
breakdown = py["metrics_breakdown"]
print(f"{model_name:<20} "
f"{breakdown.get('sv', 0):.3f} "
f"{breakdown.get('epr', 0):.3f} "
f"{breakdown.get('cqs', 0):.3f} "
f"{breakdown.get('security_score', 0):.3f} "
f"{breakdown.get('scc', 0):.3f} "
f"{py['cce_score']:.4f} "
f"{py['overall_score']:.2f}/100")
print("-" * 120)
# Formula verification
print("\n\nFORMULA VERIFICATION:")
print("CCE = α*SV + β*EPR + γ*CQS + δ*(1-SRS) + ϵ*SCC")
print("Weights: α=0.15, β=0.35, γ=0.20, δ=0.15, ϵ=0.15")
print("All metrics normalized to [0, 1]")
print("="*80)
|