Update app.py
Browse files
app.py
CHANGED
|
@@ -10,9 +10,6 @@ import gradio as gr
|
|
| 10 |
import pandas as pd
|
| 11 |
from huggingface_hub import InferenceClient
|
| 12 |
|
| 13 |
-
# ============================================================
|
| 14 |
-
# Настройки
|
| 15 |
-
# ============================================================
|
| 16 |
HF_TOKEN = os.getenv("HF_TOKEN", "").strip()
|
| 17 |
|
| 18 |
HF_MODELS = {
|
|
@@ -23,9 +20,7 @@ HF_MODELS = {
|
|
| 23 |
"Mistral-Small-24B-Instruct": "mistralai/Mistral-Small-3.1-24B-Instruct-2503",
|
| 24 |
}
|
| 25 |
|
| 26 |
-
|
| 27 |
-
# Модель результата
|
| 28 |
-
# ============================================================
|
| 29 |
@dataclass
|
| 30 |
class RequirementResult:
|
| 31 |
original_requirement: str
|
|
@@ -38,15 +33,12 @@ class RequirementResult:
|
|
| 38 |
raw_response: str
|
| 39 |
|
| 40 |
|
| 41 |
-
# ============================================================
|
| 42 |
-
# Промпт
|
| 43 |
-
# ============================================================
|
| 44 |
SYSTEM_PROMPT = """
|
| 45 |
Ты — эксперт по инженерии требований и системному анализу.
|
| 46 |
|
| 47 |
Твоя задача:
|
| 48 |
1. Проанализировать исходное требование.
|
| 49 |
-
2. Найти ошибки и проблемы качества.
|
| 50 |
3. Оценить качество исходного требования числом от 0 до 1:
|
| 51 |
- 0 = очень плохое требование
|
| 52 |
- 1 = качественное требование
|
|
@@ -81,9 +73,6 @@ def build_user_prompt(requirement: str) -> str:
|
|
| 81 |
""".strip()
|
| 82 |
|
| 83 |
|
| 84 |
-
# ============================================================
|
| 85 |
-
# Вспомогательные функции
|
| 86 |
-
# ============================================================
|
| 87 |
def make_hf_client() -> InferenceClient:
|
| 88 |
if HF_TOKEN:
|
| 89 |
return InferenceClient(token=HF_TOKEN)
|
|
@@ -103,8 +92,7 @@ def safe_json_extract(text: str) -> Dict[str, Any]:
|
|
| 103 |
|
| 104 |
match = re.search(r"\{.*\}", text, flags=re.DOTALL)
|
| 105 |
if match:
|
| 106 |
-
|
| 107 |
-
return json.loads(candidate)
|
| 108 |
|
| 109 |
raise ValueError("Модель не вернула корректный JSON")
|
| 110 |
|
|
@@ -112,10 +100,7 @@ def safe_json_extract(text: str) -> Dict[str, Any]:
|
|
| 112 |
def normalize_score(value: Any) -> Optional[float]:
|
| 113 |
try:
|
| 114 |
score = float(value)
|
| 115 |
-
|
| 116 |
-
score = 0.0
|
| 117 |
-
if score > 1:
|
| 118 |
-
score = 1.0
|
| 119 |
return round(score, 3)
|
| 120 |
except Exception:
|
| 121 |
return None
|
|
@@ -136,9 +121,6 @@ def normalize_result(data: Dict[str, Any]) -> Dict[str, Any]:
|
|
| 136 |
}
|
| 137 |
|
| 138 |
|
| 139 |
-
# ============================================================
|
| 140 |
-
# Загрузка требований
|
| 141 |
-
# ============================================================
|
| 142 |
def parse_requirements_text(raw_text: str) -> List[str]:
|
| 143 |
raw_text = (raw_text or "").strip()
|
| 144 |
if not raw_text:
|
|
@@ -185,9 +167,6 @@ def load_requirements_from_file(file_obj) -> List[str]:
|
|
| 185 |
raise ValueError("Поддерживаются только .txt и .csv")
|
| 186 |
|
| 187 |
|
| 188 |
-
# ============================================================
|
| 189 |
-
# Вызов модели
|
| 190 |
-
# ============================================================
|
| 191 |
def call_model(
|
| 192 |
model_id: str,
|
| 193 |
requirement: str,
|
|
@@ -258,9 +237,6 @@ def process_single_requirement(
|
|
| 258 |
)
|
| 259 |
|
| 260 |
|
| 261 |
-
# ============================================================
|
| 262 |
-
# Формирование результатов
|
| 263 |
-
# ============================================================
|
| 264 |
def build_results_dataframe(results: List[RequirementResult]) -> pd.DataFrame:
|
| 265 |
rows = []
|
| 266 |
|
|
@@ -289,9 +265,6 @@ def save_results(df: pd.DataFrame, raw_results: List[RequirementResult]) -> Tupl
|
|
| 289 |
return csv_path, json_path
|
| 290 |
|
| 291 |
|
| 292 |
-
# ============================================================
|
| 293 |
-
# Главная функция
|
| 294 |
-
# ============================================================
|
| 295 |
def run_benchmark(
|
| 296 |
raw_requirements: str,
|
| 297 |
uploaded_file,
|
|
@@ -323,11 +296,11 @@ def run_benchmark(
|
|
| 323 |
|
| 324 |
results: List[RequirementResult] = []
|
| 325 |
|
| 326 |
-
|
| 327 |
with ThreadPoolExecutor(max_workers=max_parallel_calls) as executor:
|
| 328 |
for req in unique_requirements:
|
| 329 |
for model_name in selected_models:
|
| 330 |
-
|
| 331 |
executor.submit(
|
| 332 |
process_single_requirement,
|
| 333 |
requirement=req,
|
|
@@ -337,7 +310,7 @@ def run_benchmark(
|
|
| 337 |
)
|
| 338 |
)
|
| 339 |
|
| 340 |
-
for future in as_completed(
|
| 341 |
results.append(future.result())
|
| 342 |
|
| 343 |
results.sort(key=lambda x: (x.original_requirement, x.model_name))
|
|
@@ -383,9 +356,6 @@ def preview_requirements(raw_requirements: str, uploaded_file):
|
|
| 383 |
return f"Найдено требований: {len(unique_requirements)}\n\n{preview}"
|
| 384 |
|
| 385 |
|
| 386 |
-
# ============================================================
|
| 387 |
-
# Интерфейс
|
| 388 |
-
# ============================================================
|
| 389 |
with gr.Blocks(title="Рефакторинг требований с помощью LLM") as demo:
|
| 390 |
gr.Markdown(
|
| 391 |
"""
|
|
|
|
| 10 |
import pandas as pd
|
| 11 |
from huggingface_hub import InferenceClient
|
| 12 |
|
|
|
|
|
|
|
|
|
|
| 13 |
HF_TOKEN = os.getenv("HF_TOKEN", "").strip()
|
| 14 |
|
| 15 |
HF_MODELS = {
|
|
|
|
| 20 |
"Mistral-Small-24B-Instruct": "mistralai/Mistral-Small-3.1-24B-Instruct-2503",
|
| 21 |
}
|
| 22 |
|
| 23 |
+
|
|
|
|
|
|
|
| 24 |
@dataclass
|
| 25 |
class RequirementResult:
|
| 26 |
original_requirement: str
|
|
|
|
| 33 |
raw_response: str
|
| 34 |
|
| 35 |
|
|
|
|
|
|
|
|
|
|
| 36 |
SYSTEM_PROMPT = """
|
| 37 |
Ты — эксперт по инженерии требований и системному анализу.
|
| 38 |
|
| 39 |
Твоя задача:
|
| 40 |
1. Проанализировать исходное требование.
|
| 41 |
+
2. Найти ошибки и проблемы качества в исходном требовании.
|
| 42 |
3. Оценить качество исходного требования числом от 0 до 1:
|
| 43 |
- 0 = очень плохое требование
|
| 44 |
- 1 = качественное требование
|
|
|
|
| 73 |
""".strip()
|
| 74 |
|
| 75 |
|
|
|
|
|
|
|
|
|
|
| 76 |
def make_hf_client() -> InferenceClient:
|
| 77 |
if HF_TOKEN:
|
| 78 |
return InferenceClient(token=HF_TOKEN)
|
|
|
|
| 92 |
|
| 93 |
match = re.search(r"\{.*\}", text, flags=re.DOTALL)
|
| 94 |
if match:
|
| 95 |
+
return json.loads(match.group(0))
|
|
|
|
| 96 |
|
| 97 |
raise ValueError("Модель не вернула корректный JSON")
|
| 98 |
|
|
|
|
| 100 |
def normalize_score(value: Any) -> Optional[float]:
|
| 101 |
try:
|
| 102 |
score = float(value)
|
| 103 |
+
score = max(0.0, min(1.0, score))
|
|
|
|
|
|
|
|
|
|
| 104 |
return round(score, 3)
|
| 105 |
except Exception:
|
| 106 |
return None
|
|
|
|
| 121 |
}
|
| 122 |
|
| 123 |
|
|
|
|
|
|
|
|
|
|
| 124 |
def parse_requirements_text(raw_text: str) -> List[str]:
|
| 125 |
raw_text = (raw_text or "").strip()
|
| 126 |
if not raw_text:
|
|
|
|
| 167 |
raise ValueError("Поддерживаются только .txt и .csv")
|
| 168 |
|
| 169 |
|
|
|
|
|
|
|
|
|
|
| 170 |
def call_model(
|
| 171 |
model_id: str,
|
| 172 |
requirement: str,
|
|
|
|
| 237 |
)
|
| 238 |
|
| 239 |
|
|
|
|
|
|
|
|
|
|
| 240 |
def build_results_dataframe(results: List[RequirementResult]) -> pd.DataFrame:
|
| 241 |
rows = []
|
| 242 |
|
|
|
|
| 265 |
return csv_path, json_path
|
| 266 |
|
| 267 |
|
|
|
|
|
|
|
|
|
|
| 268 |
def run_benchmark(
|
| 269 |
raw_requirements: str,
|
| 270 |
uploaded_file,
|
|
|
|
| 296 |
|
| 297 |
results: List[RequirementResult] = []
|
| 298 |
|
| 299 |
+
futures = []
|
| 300 |
with ThreadPoolExecutor(max_workers=max_parallel_calls) as executor:
|
| 301 |
for req in unique_requirements:
|
| 302 |
for model_name in selected_models:
|
| 303 |
+
futures.append(
|
| 304 |
executor.submit(
|
| 305 |
process_single_requirement,
|
| 306 |
requirement=req,
|
|
|
|
| 310 |
)
|
| 311 |
)
|
| 312 |
|
| 313 |
+
for future in as_completed(futures):
|
| 314 |
results.append(future.result())
|
| 315 |
|
| 316 |
results.sort(key=lambda x: (x.original_requirement, x.model_name))
|
|
|
|
| 356 |
return f"Найдено требований: {len(unique_requirements)}\n\n{preview}"
|
| 357 |
|
| 358 |
|
|
|
|
|
|
|
|
|
|
| 359 |
with gr.Blocks(title="Рефакторинг требований с помощью LLM") as demo:
|
| 360 |
gr.Markdown(
|
| 361 |
"""
|