File size: 7,763 Bytes
041d0e8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""

Gradio Space для интерактивного использования модели Code Analyzer

Модель анализирует код студента на основе условия задачи

Поддерживает как веб-интерфейс, так и API endpoint

"""
import gradio as gr
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
import json
from pydantic import BaseModel
from typing import Optional

# Загрузка модели (будет выполнена при первом запуске)
MODEL_NAME = "Vilyam888/Code_analyze.1.0"

def load_model():
    """Загружает модель один раз при старте и сохраняет в глобальные переменные"""
    global model, tokenizer
    
    if model is None or tokenizer is None:
        print("Загрузка модели...")
        tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True)
        model = AutoModelForCausalLM.from_pretrained(
            MODEL_NAME,
            torch_dtype=torch.bfloat16 if torch.cuda.is_available() else torch.float32,
            device_map="auto",
            trust_remote_code=True
        )
        print("Модель загружена успешно!")

# Глобальные переменные для модели
model, tokenizer = None, None

def build_input(task, code):
    """Форматирует вход в том же формате, что использовался при обучении"""
    parts = []
    if task.strip():
        parts.append(f"Задача:\n{task.strip()}")
    if code.strip():
        parts.append(f"Решение (код):\n```python\n{code.strip()}\n```")
    return "\n\n".join(parts)

def analyze_code(task, code):
    """Анализирует код студента и возвращает результат в формате JSON"""
    global model, tokenizer
    
    if model is None or tokenizer is None:
        return "⏳ Загрузка модели... Пожалуйста, подождите."
    
    if not task.strip():
        return "❌ Пожалуйста, введите условие задачи."
    
    if not code.strip():
        return "❌ Пожалуйста, введите код решения студента."
    
    try:
        # Форматирование входа в стиле обучения
        input_text = build_input(task, code)
        prompt = f"{input_text}\n\nОтвет:\n"
        
        # Токенизация
        inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
        
        # Генерация ответа
        with torch.no_grad():
            outputs = model.generate(
                **inputs,
                max_new_tokens=600,  # Оптимизировано для CPU
                temperature=0.7,
                top_p=0.85,
                top_k=20,
                repetition_penalty=1.05,
                do_sample=True,
                pad_token_id=tokenizer.eos_token_id,
                eos_token_id=tokenizer.eos_token_id
            )
        
        # Декодирование ответа
        response = tokenizer.decode(outputs[0], skip_special_tokens=True)
        
        # Извлечение JSON ответа
        if "Ответ:" in response:
            json_str = response.split("Ответ:")[-1].strip()
        else:
            json_str = response
        
        # Попытка распарсить JSON
        try:
            result = json.loads(json_str)
            # Форматируем JSON для красивого отображения
            return json.dumps(result, ensure_ascii=False, indent=2)
        except json.JSONDecodeError:
            # Если не JSON, возвращаем как есть
            return json_str
        
    except Exception as e:
        return f"❌ Ошибка: {str(e)}"

# Создание Gradio интерфейса
with gr.Blocks(title="Code Analyzer Model") as demo:
    gr.Markdown("""

    # 🔍 Code Analyzer Model

    

    Модель для анализа кода студента на основе условия задачи.

    

    **Как использовать:**

    1. Введите условие задачи в первое поле

    2. Введите код решения студента во второе поле

    3. Нажмите "Анализировать код"

    4. Получите детальный анализ в формате JSON

    

    **API Endpoint:** `/api/predict` - используйте для интеграции в другие проекты

    """)
    
    with gr.Row():
        with gr.Column():
            task_input = gr.Textbox(
                label="Условие задачи",
                placeholder="Введите условие задачи...",
                lines=5
            )
            code_input = gr.Textbox(
                label="Код решения студента",
                placeholder="Введите код решения...",
                lines=10
            )
            submit_btn = gr.Button("Анализировать код", variant="primary", size="lg")
        
        with gr.Column():
            result_output = gr.JSON(
                label="Результат анализа"
            )
            # Также показываем как текст для удобства копирования
            result_text = gr.Textbox(
                label="Результат (JSON текст)",
                lines=15,
                interactive=False
            )
    
    # Примеры
    gr.Examples(
        examples=[
            [
                "Напишите функцию, которая принимает список чисел и возвращает сумму всех элементов.",
                "def sum_list(numbers):\n    total = 0\n    for num in numbers:\n        total += num\n    return total"
            ],
            [
                "Создайте функцию для вычисления факториала числа.",
                "def factorial(n):\n    if n <= 1:\n        return 1\n    return n * factorial(n-1)"
            ],
        ],
        inputs=[task_input, code_input]
    )
    
    def analyze_and_format(task, code):
        """Анализирует код и форматирует результат"""
        result_str = analyze_code(task, code)
        try:
            result_json = json.loads(result_str)
            return result_json, result_str
        except:
            return None, result_str
    
    # Загрузка модели при старте
    demo.load(load_model, outputs=None)
    
    # Обработчик кнопки
    submit_btn.click(
        fn=analyze_and_format,
        inputs=[task_input, code_input],
        outputs=[result_output, result_text]
    )
    
    # Обработчик Enter в поле кода
    code_input.submit(
        fn=analyze_and_format,
        inputs=[task_input, code_input],
        outputs=[result_output, result_text]
    )

# Gradio автоматически создает API endpoint на /api/predict
# Для использования из других проектов:
# POST https://YOUR_SPACE_URL.hf.space/api/predict
# Body: {"data": ["task", "code"]}

if __name__ == "__main__":
    demo.launch(theme=gr.themes.Soft(), server_name="0.0.0.0")