Vilyam888 commited on
Commit
041d0e8
·
verified ·
1 Parent(s): 083ba1e

Upload folder using huggingface_hub

Browse files
Files changed (8) hide show
  1. API_ENDPOINT.md +279 -0
  2. API_USAGE.md +333 -0
  3. BACKEND_INTEGRATION.md +537 -0
  4. ENABLE_INFERENCE_API.md +100 -0
  5. README.md +269 -68
  6. README_SPACE.md +27 -0
  7. app.py +187 -176
  8. requirements_gradio.txt +2 -0
API_ENDPOINT.md ADDED
@@ -0,0 +1,279 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # API Endpoint для модели Code Analyzer
2
+
3
+ Модель доступна через API endpoint в Gradio Space.
4
+
5
+ ## Использование API
6
+
7
+ ### URL Endpoint
8
+
9
+ Если ваш Gradio Space доступен по адресу: `https://YOUR_USERNAME-code-analyzer-demo.hf.space`
10
+
11
+ То API endpoint будет: `https://YOUR_USERNAME-code-analyzer-demo.hf.space/api/predict`
12
+
13
+ ### Формат запроса
14
+
15
+ **Метод:** POST
16
+ **Content-Type:** application/json
17
+
18
+ **Body:**
19
+ ```json
20
+ {
21
+ "data": [
22
+ "Условие задачи",
23
+ "Код студента"
24
+ ]
25
+ }
26
+ ```
27
+
28
+ ### Формат ответа
29
+
30
+ ```json
31
+ {
32
+ "data": [
33
+ {
34
+ "summary": "...",
35
+ "tags": [...],
36
+ "overall_score": 10,
37
+ ...
38
+ },
39
+ "JSON строка"
40
+ ]
41
+ }
42
+ ```
43
+
44
+ ## Примеры использования
45
+
46
+ ### Python
47
+
48
+ ```python
49
+ import requests
50
+ import json
51
+
52
+ # URL вашего Gradio Space
53
+ SPACE_URL = "https://YOUR_USERNAME-code-analyzer-demo.hf.space"
54
+
55
+ def analyze_code(task, code):
56
+ """Анализирует код через API"""
57
+ api_url = f"{SPACE_URL}/api/predict"
58
+
59
+ payload = {
60
+ "data": [task, code]
61
+ }
62
+
63
+ response = requests.post(api_url, json=payload)
64
+ result = response.json()
65
+
66
+ # Gradio возвращает результат в формате {"data": [json_obj, json_str]}
67
+ if "data" in result and len(result["data"]) > 0:
68
+ # Первый элемент - это JSON объект
69
+ return result["data"][0]
70
+ return result
71
+
72
+ # Использование
73
+ task = "Напишите функцию для вычисления суммы списка"
74
+ code = """def sum_list(numbers):
75
+ return sum(numbers)"""
76
+
77
+ result = analyze_code(task, code)
78
+ print(json.dumps(result, ensure_ascii=False, indent=2))
79
+ ```
80
+
81
+ ### JavaScript/Node.js
82
+
83
+ ```javascript
84
+ const axios = require('axios');
85
+
86
+ const SPACE_URL = 'https://YOUR_USERNAME-code-analyzer-demo.hf.space';
87
+
88
+ async function analyzeCode(task, code) {
89
+ try {
90
+ const response = await axios.post(
91
+ `${SPACE_URL}/api/predict`,
92
+ {
93
+ data: [task, code]
94
+ }
95
+ );
96
+
97
+ // Gradio возвращает {"data": [json_obj, json_str]}
98
+ return response.data.data[0];
99
+ } catch (error) {
100
+ console.error('Ошибка:', error.message);
101
+ throw error;
102
+ }
103
+ }
104
+
105
+ // Использование
106
+ analyzeCode(
107
+ "Напишите функцию для суммы списка",
108
+ "def sum_list(numbers):\n return sum(numbers)"
109
+ ).then(result => {
110
+ console.log(JSON.stringify(result, null, 2));
111
+ });
112
+ ```
113
+
114
+ ### cURL
115
+
116
+ ```bash
117
+ curl -X POST https://YOUR_USERNAME-code-analyzer-demo.hf.space/api/predict \
118
+ -H "Content-Type: application/json" \
119
+ -d '{
120
+ "data": [
121
+ "Напишите функцию для вычисления суммы списка",
122
+ "def sum_list(numbers):\n return sum(numbers)"
123
+ ]
124
+ }'
125
+ ```
126
+
127
+ ### PHP
128
+
129
+ ```php
130
+ <?php
131
+ $spaceUrl = 'https://YOUR_USERNAME-code-analyzer-demo.hf.space/api/predict';
132
+
133
+ $task = "Напишите функцию для вычисления суммы списка";
134
+ $code = "def sum_list(numbers):\n return sum(numbers)";
135
+
136
+ $data = [
137
+ 'data' => [$task, $code]
138
+ ];
139
+
140
+ $ch = curl_init($spaceUrl);
141
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
142
+ curl_setopt($ch, CURLOPT_POST, true);
143
+ curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
144
+ curl_setopt($ch, CURLOPT_HTTPHEADER, [
145
+ 'Content-Type: application/json'
146
+ ]);
147
+
148
+ $response = curl_exec($ch);
149
+ curl_close($ch);
150
+
151
+ $result = json_decode($response, true);
152
+ $analysis = $result['data'][0]; // JSON объект с анализом
153
+
154
+ echo json_encode($analysis, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
155
+ ?>
156
+ ```
157
+
158
+ ## Интеграция в Backend
159
+
160
+ ### FastAPI
161
+
162
+ ```python
163
+ from fastapi import FastAPI
164
+ import requests
165
+
166
+ app = FastAPI()
167
+ SPACE_URL = "https://YOUR_USERNAME-code-analyzer-demo.hf.space"
168
+
169
+ @app.post("/analyze")
170
+ async def analyze_code(request: dict):
171
+ task = request.get("task")
172
+ code = request.get("code")
173
+
174
+ # Вызов Gradio API
175
+ response = requests.post(
176
+ f"{SPACE_URL}/api/predict",
177
+ json={"data": [task, code]},
178
+ timeout=180 # 3 минуты для CPU
179
+ )
180
+
181
+ result = response.json()
182
+ return {"success": True, "analysis": result["data"][0]}
183
+ ```
184
+
185
+ ### Express.js
186
+
187
+ ```javascript
188
+ const express = require('express');
189
+ const axios = require('axios');
190
+
191
+ const app = express();
192
+ app.use(express.json());
193
+
194
+ const SPACE_URL = 'https://YOUR_USERNAME-code-analyzer-demo.hf.space';
195
+
196
+ app.post('/analyze', async (req, res) => {
197
+ const { task, code } = req.body;
198
+
199
+ try {
200
+ const response = await axios.post(
201
+ `${SPACE_URL}/api/predict`,
202
+ { data: [task, code] },
203
+ { timeout: 180000 } // 3 минуты
204
+ );
205
+
206
+ res.json({
207
+ success: true,
208
+ analysis: response.data.data[0]
209
+ });
210
+ } catch (error) {
211
+ res.status(500).json({
212
+ success: false,
213
+ error: error.message
214
+ });
215
+ }
216
+ });
217
+
218
+ app.listen(8000);
219
+ ```
220
+
221
+ ## Обработка ошибок
222
+
223
+ ```python
224
+ import requests
225
+ import time
226
+
227
+ def analyze_with_retry(task, code, max_retries=3):
228
+ """Анализ с повторными попытками"""
229
+ for attempt in range(max_retries):
230
+ try:
231
+ response = requests.post(
232
+ f"{SPACE_URL}/api/predict",
233
+ json={"data": [task, code]},
234
+ timeout=180
235
+ )
236
+
237
+ if response.status_code == 200:
238
+ return response.json()["data"][0]
239
+ else:
240
+ print(f"Ошибка {response.status_code}: {response.text}")
241
+
242
+ except requests.exceptions.Timeout:
243
+ print(f"Таймаут на попытке {attempt + 1}")
244
+ if attempt < max_retries - 1:
245
+ time.sleep(5) # Ждем 5 секунд перед повтором
246
+ except Exception as e:
247
+ print(f"Ошибка: {e}")
248
+ if attempt < max_retries - 1:
249
+ time.sleep(5)
250
+
251
+ return None
252
+ ```
253
+
254
+ ## Ограничения
255
+
256
+ - **Таймаут:** Рекомендуется устанавливать таймаут 180 секунд (3 минуты) для CPU
257
+ - **Rate Limiting:** Gradio Space может иметь ограничения на количество запросов
258
+ - **Очередь:** Если Space занят, запрос может быть поставлен в очередь
259
+
260
+ ## Альтернатива: Прямое использование модели
261
+
262
+ Если нужен более надежный API, можно развернуть модель локально или на своем сервере:
263
+
264
+ ```python
265
+ # См. BACKEND_INTEGRATION.md для примеров
266
+ from transformers import AutoModelForCausalLM, AutoTokenizer
267
+ # ... (полный код в BACKEND_INTEGRATION.md)
268
+ ```
269
+
270
+ ## Получение URL вашего Space
271
+
272
+ 1. Перейдите на https://huggingface.co/spaces
273
+ 2. Найдите ваш Space
274
+ 3. Скопируйте URL (например: `https://username-code-analyzer-demo.hf.space`)
275
+ 4. Используйте `/api/predict` для API endpoint
276
+
277
+ ---
278
+
279
+ **Готово!** Теперь вы можете использовать модель через API из любого проекта.
API_USAGE.md ADDED
@@ -0,0 +1,333 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Использование модели через Hugging Face API
2
+
3
+ Эта модель доступна на Hugging Face и может быть использована другими пользователями через несколько способов.
4
+
5
+ ## Способ 1: Использование через transformers (рекомендуется)
6
+
7
+ ### Установка зависимостей
8
+
9
+ ```bash
10
+ pip install transformers torch
11
+ ```
12
+
13
+ ### Базовый пример
14
+
15
+ ```python
16
+ from transformers import AutoModelForCausalLM, AutoTokenizer
17
+ import torch
18
+ import json
19
+
20
+ # Имя модели на Hugging Face
21
+ model_name = "Vilyam888/Code_analyze.1.0"
22
+
23
+ # Загрузка модели и токенизатора
24
+ tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)
25
+ model = AutoModelForCausalLM.from_pretrained(
26
+ model_name,
27
+ torch_dtype=torch.bfloat16 if torch.cuda.is_available() else torch.float32,
28
+ device_map="auto",
29
+ trust_remote_code=True
30
+ )
31
+
32
+ # Условие задачи
33
+ task = "Напишите функцию, которая принимает список чисел и возвращает сумму всех элементов."
34
+
35
+ # Код студента
36
+ code = """def sum_list(numbers):
37
+ total = 0
38
+ for num in numbers:
39
+ total += num
40
+ return total"""
41
+
42
+ # Форматирование входа
43
+ input_text = f"Задача:\n{task}\n\nРешение (код):\n```python\n{code}\n```"
44
+ prompt = f"{input_text}\n\nОтвет:\n"
45
+
46
+ # Генерация анализа
47
+ inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
48
+ with torch.no_grad():
49
+ outputs = model.generate(
50
+ **inputs,
51
+ max_new_tokens=600,
52
+ temperature=0.7,
53
+ top_p=0.85,
54
+ top_k=20,
55
+ repetition_penalty=1.05,
56
+ do_sample=True,
57
+ pad_token_id=tokenizer.eos_token_id
58
+ )
59
+
60
+ # Декодирование и парсинг JSON
61
+ response = tokenizer.decode(outputs[0], skip_special_tokens=True)
62
+ result = response.split("Ответ:")[-1].strip()
63
+ analysis = json.loads(result)
64
+
65
+ print(json.dumps(analysis, ensure_ascii=False, indent=2))
66
+ ```
67
+
68
+ ## Способ 2: Использование через Hugging Face Inference API
69
+
70
+ Если Inference API доступен для вашей модели, можно использовать его:
71
+
72
+ ```python
73
+ import requests
74
+ import json
75
+
76
+ API_URL = "https://api-inference.huggingface.co/models/Vilyam888/Code_analyze.1.0"
77
+ headers = {"Authorization": "Bearer YOUR_HF_TOKEN"} # Замените на ваш токен
78
+
79
+ def analyze_code(task, code):
80
+ # Форматирование входа
81
+ input_text = f"Задача:\n{task}\n\nРешение (код):\n```python\n{code}\n```"
82
+ prompt = f"{input_text}\n\nОтвет:\n"
83
+
84
+ payload = {
85
+ "inputs": prompt,
86
+ "parameters": {
87
+ "max_new_tokens": 600,
88
+ "temperature": 0.7,
89
+ "top_p": 0.85,
90
+ "top_k": 20,
91
+ "repetition_penalty": 1.05,
92
+ "return_full_text": False
93
+ }
94
+ }
95
+
96
+ response = requests.post(API_URL, headers=headers, json=payload)
97
+ result = response.json()
98
+
99
+ # Извлечение текста
100
+ if isinstance(result, list) and len(result) > 0:
101
+ generated_text = result[0].get("generated_text", "")
102
+ else:
103
+ generated_text = result.get("generated_text", "")
104
+
105
+ # Парсинг JSON
106
+ try:
107
+ analysis = json.loads(generated_text)
108
+ return analysis
109
+ except json.JSONDecodeError:
110
+ return {"raw_response": generated_text}
111
+
112
+ # Пример использования
113
+ task = "Напишите функцию для вычисления факториала."
114
+ code = """def factorial(n):
115
+ if n <= 1:
116
+ return 1
117
+ return n * factorial(n-1)"""
118
+
119
+ result = analyze_code(task, code)
120
+ print(json.dumps(result, ensure_ascii=False, indent=2))
121
+ ```
122
+
123
+ **Примечание:** Для использования Inference API нужен токен Hugging Face. Получите его на https://huggingface.co/settings/tokens
124
+
125
+ ## Способ 3: Использование через Gradio API (если создан Space)
126
+
127
+ Если вы создали Gradio Space, можно использовать его API:
128
+
129
+ ```python
130
+ import requests
131
+ import json
132
+
133
+ # URL вашего Gradio Space
134
+ SPACE_URL = "https://YOUR_USERNAME-code-analyzer-demo.hf.space" # Замените на ваш URL
135
+
136
+ def analyze_via_gradio(task, code):
137
+ # Gradio API endpoint
138
+ api_url = f"{SPACE_URL}/api/predict"
139
+
140
+ payload = {
141
+ "data": [task, code]
142
+ }
143
+
144
+ response = requests.post(api_url, json=payload)
145
+ result = response.json()
146
+
147
+ # Gradio возвращает результат в формате {"data": [...]}
148
+ if "data" in result and len(result["data"]) > 0:
149
+ return result["data"][0] # JSON объект
150
+ return result
151
+
152
+ # Пример использования
153
+ task = "Напишите функцию для вычисления суммы списка."
154
+ code = "def sum_list(numbers):\n return sum(numbers)"
155
+
156
+ result = analyze_via_gradio(task, code)
157
+ print(json.dumps(result, ensure_ascii=False, indent=2))
158
+ ```
159
+
160
+ ## Способ 4: Использование готовых скриптов из репозитория
161
+
162
+ Склонируйте репозиторий и используйте готовые примеры:
163
+
164
+ ```bash
165
+ git clone https://huggingface.co/Vilyam888/Code_analyze.1.0
166
+ cd Code_analyze.1.0
167
+ ```
168
+
169
+ Или используйте примеры из этого проекта:
170
+ - `scripts/quick_start_example.py` - минимальный пример
171
+ - `scripts/use_model_example.py` - полный пример с интерактивным режимом
172
+ - `models/merged/qwen_merged_full/inference.py` - функции для использования
173
+
174
+ ## Формат входных данных
175
+
176
+ Модель ожидает два параметра:
177
+
178
+ 1. **task** (str): Условие задачи
179
+ ```
180
+ "Напишите функцию, которая принимает список чисел и возвращает сумму всех элементов."
181
+ ```
182
+
183
+ 2. **code** (str): Код решения студента
184
+ ```python
185
+ """def sum_list(numbers):
186
+ total = 0
187
+ for num in numbers:
188
+ total += num
189
+ return total"""
190
+ ```
191
+
192
+ ## Формат выходных данных
193
+
194
+ Модель возвращает JSON объект в следующем формате:
195
+
196
+ ```json
197
+ {
198
+ "summary": "Краткое резюме анализа",
199
+ "tags": [
200
+ {
201
+ "name": "Python",
202
+ "weight": 0.25,
203
+ "applied": true,
204
+ "score": 10,
205
+ "evidence": "Обоснование оценки"
206
+ }
207
+ ],
208
+ "overall_score": 10,
209
+ "code_quality_score": 9.5,
210
+ "correctness": {
211
+ "is_correct": true,
212
+ "score": 10,
213
+ "edge_cases_handled": true
214
+ },
215
+ "task_compliance": {
216
+ "is_relevant": true,
217
+ "score": 10,
218
+ "description": "Описание соответствия требованиям",
219
+ "missing_requirements": [],
220
+ "extra_features": []
221
+ },
222
+ "strengths": ["Сильные стороны решения"],
223
+ "weaknesses": ["Слабые стороны"],
224
+ "recommendations": ["Рекомендации по улучшению"],
225
+ "detailed_analysis": "Детальный анализ решения"
226
+ }
227
+ ```
228
+
229
+ ## Примеры использования
230
+
231
+ ### Python
232
+
233
+ ```python
234
+ from transformers import AutoModelForCausalLM, AutoTokenizer
235
+ import torch
236
+ import json
237
+
238
+ model_name = "Vilyam888/Code_analyze.1.0"
239
+ tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)
240
+ model = AutoModelForCausalLM.from_pretrained(
241
+ model_name,
242
+ torch_dtype=torch.bfloat16 if torch.cuda.is_available() else torch.float32,
243
+ device_map="auto",
244
+ trust_remote_code=True
245
+ )
246
+
247
+ def analyze(task, code):
248
+ input_text = f"Задача:\n{task}\n\nРешение (код):\n```python\n{code}\n```"
249
+ prompt = f"{input_text}\n\nОтвет:\n"
250
+
251
+ inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
252
+ with torch.no_grad():
253
+ outputs = model.generate(
254
+ **inputs,
255
+ max_new_tokens=600,
256
+ temperature=0.7,
257
+ top_p=0.85,
258
+ top_k=20,
259
+ repetition_penalty=1.05,
260
+ do_sample=True,
261
+ pad_token_id=tokenizer.eos_token_id
262
+ )
263
+
264
+ response = tokenizer.decode(outputs[0], skip_special_tokens=True)
265
+ result = response.split("Ответ:")[-1].strip()
266
+ return json.loads(result)
267
+
268
+ # Использование
269
+ result = analyze(
270
+ task="Напишите функцию для вычисления факториала",
271
+ code="def factorial(n):\n return 1 if n <= 1 else n * factorial(n-1)"
272
+ )
273
+ print(json.dumps(result, ensure_ascii=False, indent=2))
274
+ ```
275
+
276
+ ### JavaScript/Node.js
277
+
278
+ ```javascript
279
+ const fetch = require('node-fetch');
280
+ const { pipeline } = require('@huggingface/inference');
281
+
282
+ async function analyzeCode(task, code) {
283
+ const hf = new HfInference('YOUR_HF_TOKEN'); // Замените на ваш токен
284
+
285
+ const inputText = `Задача:\n${task}\n\nРешение (код):\n\`\`\`python\n${code}\n\`\`\``;
286
+ const prompt = `${inputText}\n\nОтвет:\n`;
287
+
288
+ const result = await hf.textGeneration({
289
+ model: 'Vilyam888/Code_analyze.1.0',
290
+ inputs: prompt,
291
+ parameters: {
292
+ max_new_tokens: 600,
293
+ temperature: 0.7,
294
+ top_p: 0.85,
295
+ top_k: 20,
296
+ repetition_penalty: 1.05
297
+ }
298
+ });
299
+
300
+ const response = result.generated_text;
301
+ const jsonStr = response.split('Ответ:')[1]?.trim() || response;
302
+
303
+ return JSON.parse(jsonStr);
304
+ }
305
+
306
+ // Использование
307
+ analyzeCode(
308
+ "Напишите функцию для вычисления суммы списка",
309
+ "def sum_list(numbers):\n return sum(numbers)"
310
+ ).then(result => console.log(JSON.stringify(result, null, 2)));
311
+ ```
312
+
313
+ ## Требования
314
+
315
+ - Python 3.8+
316
+ - PyTorch 2.0+
317
+ - transformers 5.0+
318
+ - ~6GB свободного места на диске (для загрузки модели)
319
+ - GPU рекомендуется для быстрой работы (опционально)
320
+
321
+ ## Дополнительная информация
322
+
323
+ - **Модель:** Vilyam888/Code_analyze.1.0
324
+ - **Базовая модель:** Qwen/Qwen2.5-Coder-3B-Instruct
325
+ - **Лицензия:** Apache 2.0
326
+ - **Страница модели:** https://huggingface.co/Vilyam888/Code_analyze.1.0
327
+
328
+ ## Поддержка
329
+
330
+ Если у вас возникли вопросы или проблемы:
331
+ 1. Проверьте документацию на странице модели
332
+ 2. Откройте issue в репозитории
333
+ 3. Используйте примеры из этого файла
BACKEND_INTEGRATION.md ADDED
@@ -0,0 +1,537 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Интеграция модели в Backend проект
2
+
3
+ Примеры подключения модели Code Analyzer к различным backend фреймворкам.
4
+
5
+ ## Общая информация
6
+
7
+ **Модель:** `Vilyam888/Code_analyze.1.0`
8
+ **Тип:** Text Generation (JSON ответ)
9
+ **Формат входа:** `task` (условие задачи) + `code` (код студента)
10
+ **Формат выхода:** JSON объект с анализом
11
+
12
+ ---
13
+
14
+ ## Python Backend
15
+
16
+ ### 1. FastAPI
17
+
18
+ ```python
19
+ from fastapi import FastAPI, HTTPException
20
+ from pydantic import BaseModel
21
+ from transformers import AutoModelForCausalLM, AutoTokenizer
22
+ import torch
23
+ import json
24
+
25
+ app = FastAPI(title="Code Analyzer API")
26
+
27
+ # Глобальные переменные для модели
28
+ model = None
29
+ tokenizer = None
30
+ MODEL_NAME = "Vilyam888/Code_analyze.1.0"
31
+
32
+ class AnalysisRequest(BaseModel):
33
+ task: str
34
+ code: str
35
+
36
+ class AnalysisResponse(BaseModel):
37
+ success: bool
38
+ analysis: dict
39
+
40
+ @app.on_event("startup")
41
+ async def load_model():
42
+ """Загружает модель при старте сервера"""
43
+ global model, tokenizer
44
+ print("Загрузка модели...")
45
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True)
46
+ model = AutoModelForCausalLM.from_pretrained(
47
+ MODEL_NAME,
48
+ torch_dtype=torch.bfloat16 if torch.cuda.is_available() else torch.float32,
49
+ device_map="auto",
50
+ trust_remote_code=True
51
+ )
52
+ print("Модель загружена!")
53
+
54
+ def build_input(task, code):
55
+ """Форматирует вход"""
56
+ parts = []
57
+ if task.strip():
58
+ parts.append(f"Задача:\n{task.strip()}")
59
+ if code.strip():
60
+ parts.append(f"Решение (код):\n```python\n{code.strip()}\n```")
61
+ return "\n\n".join(parts)
62
+
63
+ @app.post("/analyze", response_model=AnalysisResponse)
64
+ async def analyze_code(request: AnalysisRequest):
65
+ """Анализирует код студента"""
66
+ if model is None or tokenizer is None:
67
+ raise HTTPException(status_code=503, detail="Модель еще не загружена")
68
+
69
+ # Форматирование входа
70
+ input_text = build_input(request.task, request.code)
71
+ prompt = f"{input_text}\n\nОтвет:\n"
72
+
73
+ # Генерация
74
+ inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
75
+ with torch.no_grad():
76
+ outputs = model.generate(
77
+ **inputs,
78
+ max_new_tokens=600,
79
+ temperature=0.7,
80
+ top_p=0.85,
81
+ top_k=20,
82
+ repetition_penalty=1.05,
83
+ do_sample=True,
84
+ pad_token_id=tokenizer.eos_token_id
85
+ )
86
+
87
+ # Декодирование и парсинг JSON
88
+ response = tokenizer.decode(outputs[0], skip_special_tokens=True)
89
+ json_str = response.split("Ответ:")[-1].strip()
90
+
91
+ try:
92
+ analysis = json.loads(json_str)
93
+ return AnalysisResponse(success=True, analysis=analysis)
94
+ except json.JSONDecodeError:
95
+ raise HTTPException(status_code=500, detail="Ошибка парсинга JSON")
96
+
97
+ # Запуск: uvicorn main:app --host 0.0.0.0 --port 8000
98
+ ```
99
+
100
+ ### 2. Flask
101
+
102
+ ```python
103
+ from flask import Flask, request, jsonify
104
+ from transformers import AutoModelForCausalLM, AutoTokenizer
105
+ import torch
106
+ import json
107
+
108
+ app = Flask(__name__)
109
+
110
+ MODEL_NAME = "Vilyam888/Code_analyze.1.0"
111
+ model = None
112
+ tokenizer = None
113
+
114
+ def load_model():
115
+ """Загружает модель"""
116
+ global model, tokenizer
117
+ if model is None:
118
+ print("Загрузка модели...")
119
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True)
120
+ model = AutoModelForCausalLM.from_pretrained(
121
+ MODEL_NAME,
122
+ torch_dtype=torch.bfloat16 if torch.cuda.is_available() else torch.float32,
123
+ device_map="auto",
124
+ trust_remote_code=True
125
+ )
126
+ print("Модель загружена!")
127
+
128
+ def build_input(task, code):
129
+ parts = []
130
+ if task.strip():
131
+ parts.append(f"Задача:\n{task.strip()}")
132
+ if code.strip():
133
+ parts.append(f"Решение (код):\n```python\n{code.strip()}\n```")
134
+ return "\n\n".join(parts)
135
+
136
+ @app.route('/analyze', methods=['POST'])
137
+ def analyze():
138
+ """Анализирует код"""
139
+ load_model()
140
+
141
+ data = request.json
142
+ task = data.get('task', '')
143
+ code = data.get('code', '')
144
+
145
+ if not task or not code:
146
+ return jsonify({'error': 'task и code обязательны'}), 400
147
+
148
+ # Генерация
149
+ input_text = build_input(task, code)
150
+ prompt = f"{input_text}\n\nОтвет:\n"
151
+ inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
152
+
153
+ with torch.no_grad():
154
+ outputs = model.generate(
155
+ **inputs,
156
+ max_new_tokens=600,
157
+ temperature=0.7,
158
+ top_p=0.85,
159
+ top_k=20,
160
+ repetition_penalty=1.05,
161
+ do_sample=True,
162
+ pad_token_id=tokenizer.eos_token_id
163
+ )
164
+
165
+ response = tokenizer.decode(outputs[0], skip_special_tokens=True)
166
+ json_str = response.split("Ответ:")[-1].strip()
167
+
168
+ try:
169
+ analysis = json.loads(json_str)
170
+ return jsonify({'success': True, 'analysis': analysis})
171
+ except json.JSONDecodeError:
172
+ return jsonify({'error': 'Ошибка парсинга JSON', 'raw': json_str}), 500
173
+
174
+ if __name__ == '__main__':
175
+ app.run(host='0.0.0.0', port=8000)
176
+ ```
177
+
178
+ ### 3. Django REST Framework
179
+
180
+ ```python
181
+ # views.py
182
+ from rest_framework.views import APIView
183
+ from rest_framework.response import Response
184
+ from rest_framework import status
185
+ from transformers import AutoModelForCausalLM, AutoTokenizer
186
+ import torch
187
+ import json
188
+
189
+ MODEL_NAME = "Vilyam888/Code_analyze.1.0"
190
+ model = None
191
+ tokenizer = None
192
+
193
+ def load_model():
194
+ global model, tokenizer
195
+ if model is None:
196
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True)
197
+ model = AutoModelForCausalLM.from_pretrained(
198
+ MODEL_NAME,
199
+ torch_dtype=torch.bfloat16 if torch.cuda.is_available() else torch.float32,
200
+ device_map="auto",
201
+ trust_remote_code=True
202
+ )
203
+
204
+ class AnalyzeCodeView(APIView):
205
+ def post(self, request):
206
+ load_model()
207
+
208
+ task = request.data.get('task', '')
209
+ code = request.data.get('code', '')
210
+
211
+ if not task or not code:
212
+ return Response(
213
+ {'error': 'task и code обязательны'},
214
+ status=status.HTTP_400_BAD_REQUEST
215
+ )
216
+
217
+ # Генерация анализа
218
+ input_text = f"Задача:\n{task}\n\nРешение (код):\n```python\n{code}\n```"
219
+ prompt = f"{input_text}\n\nОтвет:\n"
220
+ inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
221
+
222
+ with torch.no_grad():
223
+ outputs = model.generate(
224
+ **inputs,
225
+ max_new_tokens=600,
226
+ temperature=0.7,
227
+ top_p=0.85,
228
+ top_k=20,
229
+ repetition_penalty=1.05,
230
+ do_sample=True,
231
+ pad_token_id=tokenizer.eos_token_id
232
+ )
233
+
234
+ response = tokenizer.decode(outputs[0], skip_special_tokens=True)
235
+ json_str = response.split("Ответ:")[-1].strip()
236
+
237
+ try:
238
+ analysis = json.loads(json_str)
239
+ return Response({'success': True, 'analysis': analysis})
240
+ except json.JSONDecodeError:
241
+ return Response(
242
+ {'error': 'Ошибка парсинга JSON'},
243
+ status=status.HTTP_500_INTERNAL_SERVER_ERROR
244
+ )
245
+ ```
246
+
247
+ ```python
248
+ # urls.py
249
+ from django.urls import path
250
+ from .views import AnalyzeCodeView
251
+
252
+ urlpatterns = [
253
+ path('api/analyze/', AnalyzeCodeView.as_view(), name='analyze'),
254
+ ]
255
+ ```
256
+
257
+ ---
258
+
259
+ ## Node.js / Express
260
+
261
+ ```javascript
262
+ const express = require('express');
263
+ const { PythonShell } = require('python-shell'); // или используйте child_process
264
+ const app = express();
265
+
266
+ app.use(express.json());
267
+
268
+ // Вариант 1: Вызов Python скрипта через child_process
269
+ const { spawn } = require('child_process');
270
+
271
+ app.post('/analyze', async (req, res) => {
272
+ const { task, code } = req.body;
273
+
274
+ if (!task || !code) {
275
+ return res.status(400).json({ error: 'task и code обязательны' });
276
+ }
277
+
278
+ // Вызов Python скрипта
279
+ const python = spawn('python', ['analyze.py', JSON.stringify({ task, code })]);
280
+ let result = '';
281
+
282
+ python.stdout.on('data', (data) => {
283
+ result += data.toString();
284
+ });
285
+
286
+ python.on('close', (code) => {
287
+ if (code !== 0) {
288
+ return res.status(500).json({ error: 'Ошибка выполнения анализа' });
289
+ }
290
+
291
+ try {
292
+ const analysis = JSON.parse(result);
293
+ res.json({ success: true, analysis });
294
+ } catch (e) {
295
+ res.status(500).json({ error: 'Ошибка парсинга JSON' });
296
+ }
297
+ });
298
+ });
299
+
300
+ // Вариант 2: Использование Hugging Face Inference API
301
+ const axios = require('axios');
302
+
303
+ app.post('/analyze', async (req, res) => {
304
+ const { task, code } = req.body;
305
+
306
+ if (!task || !code) {
307
+ return res.status(400).json({ error: 'task и code обязательны' });
308
+ }
309
+
310
+ const inputText = `Задача:\n${task}\n\nРешение (код):\n\`\`\`python\n${code}\n\`\`\``;
311
+ const prompt = `${inputText}\n\nОтвет:\n`;
312
+
313
+ try {
314
+ const response = await axios.post(
315
+ 'https://api-inference.huggingface.co/models/Vilyam888/Code_analyze.1.0',
316
+ {
317
+ inputs: prompt,
318
+ parameters: {
319
+ max_new_tokens: 600,
320
+ temperature: 0.7,
321
+ top_p: 0.85,
322
+ top_k: 20,
323
+ repetition_penalty: 1.05
324
+ }
325
+ },
326
+ {
327
+ headers: {
328
+ 'Authorization': `Bearer ${process.env.HF_TOKEN}`
329
+ }
330
+ }
331
+ );
332
+
333
+ const generatedText = response.data[0].generated_text;
334
+ const jsonStr = generatedText.split('Ответ:')[1]?.trim() || generatedText;
335
+
336
+ try {
337
+ const analysis = JSON.parse(jsonStr);
338
+ res.json({ success: true, analysis });
339
+ } catch (e) {
340
+ res.status(500).json({ error: 'Ошибка парсинга JSON', raw: jsonStr });
341
+ }
342
+ } catch (error) {
343
+ res.status(500).json({ error: error.message });
344
+ }
345
+ });
346
+
347
+ app.listen(8000, () => {
348
+ console.log('Server running on port 8000');
349
+ });
350
+ ```
351
+
352
+ ---
353
+
354
+ ## Использование как отдельный сервис (микросервис)
355
+
356
+ ### Docker контейнер
357
+
358
+ ```dockerfile
359
+ # Dockerfile
360
+ FROM python:3.10-slim
361
+
362
+ WORKDIR /app
363
+
364
+ # Установка зависимостей
365
+ COPY requirements.txt .
366
+ RUN pip install --no-cache-dir -r requirements.txt
367
+
368
+ # Копирование кода
369
+ COPY . .
370
+
371
+ # Запуск API сервера
372
+ CMD ["uvicorn", "api_server:app", "--host", "0.0.0.0", "--port", "8000"]
373
+ ```
374
+
375
+ ```yaml
376
+ # docker-compose.yml
377
+ version: '3.8'
378
+
379
+ services:
380
+ code-analyzer:
381
+ build: .
382
+ ports:
383
+ - "8000:8000"
384
+ environment:
385
+ - CUDA_VISIBLE_DEVICES=0 # Если есть GPU
386
+ volumes:
387
+ - ./models:/app/models
388
+ deploy:
389
+ resources:
390
+ reservations:
391
+ devices:
392
+ - driver: nvidia
393
+ count: 1
394
+ capabilities: [gpu]
395
+ ```
396
+
397
+ ### Вызов из другого сервиса
398
+
399
+ ```python
400
+ # В вашем основном backend проекте
401
+ import requests
402
+
403
+ def analyze_student_code(task, code):
404
+ """Вызывает микросервис анализа кода"""
405
+ response = requests.post(
406
+ 'http://code-analyzer:8000/analyze', # или ваш URL
407
+ json={'task': task, 'code': code},
408
+ timeout=180 # 3 минуты для CPU
409
+ )
410
+ return response.json()
411
+
412
+ # Использование
413
+ result = analyze_student_code(
414
+ task="Напишите функцию для суммы списка",
415
+ code="def sum_list(numbers):\n return sum(numbers)"
416
+ )
417
+ print(result['analysis'])
418
+ ```
419
+
420
+ ---
421
+
422
+ ## Кэширование результатов
423
+
424
+ Для оптиционализации можно добавить кэширование:
425
+
426
+ ```python
427
+ from functools import lru_cache
428
+ import hashlib
429
+ import json
430
+
431
+ def get_cache_key(task, code):
432
+ """Генерирует ключ кэша"""
433
+ content = f"{task}|{code}"
434
+ return hashlib.md5(content.encode()).hexdigest()
435
+
436
+ # Использование Redis для кэширования
437
+ import redis
438
+
439
+ redis_client = redis.Redis(host='localhost', port=6379, db=0)
440
+
441
+ @app.post("/analyze")
442
+ async def analyze_code(request: AnalysisRequest):
443
+ cache_key = get_cache_key(request.task, request.code)
444
+
445
+ # Проверка кэша
446
+ cached = redis_client.get(cache_key)
447
+ if cached:
448
+ return json.loads(cached)
449
+
450
+ # Генерация анализа
451
+ analysis = generate_analysis(request.task, request.code)
452
+
453
+ # Сохранение в кэш (TTL 1 час)
454
+ redis_client.setex(cache_key, 3600, json.dumps(analysis))
455
+
456
+ return analysis
457
+ ```
458
+
459
+ ---
460
+
461
+ ## Обработка ошибок и таймауты
462
+
463
+ ```python
464
+ import asyncio
465
+ from fastapi import HTTPException
466
+
467
+ @app.post("/analyze")
468
+ async def analyze_code(request: AnalysisRequest):
469
+ try:
470
+ # Таймаут 3 минуты
471
+ analysis = await asyncio.wait_for(
472
+ generate_analysis_async(request.task, request.code),
473
+ timeout=180.0
474
+ )
475
+ return analysis
476
+ except asyncio.TimeoutError:
477
+ raise HTTPException(
478
+ status_code=504,
479
+ detail="Анализ занял слишком много времени"
480
+ )
481
+ except Exception as e:
482
+ raise HTTPException(
483
+ status_code=500,
484
+ detail=f"Ошибка при анализе: {str(e)}"
485
+ )
486
+ ```
487
+
488
+ ---
489
+
490
+ ## Пример requirements.txt
491
+
492
+ ```txt
493
+ fastapi==0.104.1
494
+ uvicorn[standard]==0.24.0
495
+ transformers==5.0.0
496
+ torch==2.1.0
497
+ accelerate==0.25.0
498
+ sentencepiece==0.1.99
499
+ pydantic==2.5.0
500
+ ```
501
+
502
+ ---
503
+
504
+ ## Рекомендации по развертыванию
505
+
506
+ 1. **GPU рекомендуется** - для быстрой работы (10-30 сек вместо 1-3 мин)
507
+ 2. **Кэширование** - для повторяющихся запросов
508
+ 3. **Очередь задач** - для обработки множественных запросов (Celery, RQ)
509
+ 4. **Мониторинг** - отслеживание времени ответа и ошибок
510
+ 5. **Rate limiting** - ограничение количества запросов
511
+
512
+ ---
513
+
514
+ ## Быстрый старт
515
+
516
+ 1. Установите зависимости:
517
+ ```bash
518
+ pip install transformers torch fastapi uvicorn
519
+ ```
520
+
521
+ 2. Скопируйте код из примеров выше
522
+
523
+ 3. Запустите сервер:
524
+ ```bash
525
+ uvicorn main:app --host 0.0.0.0 --port 8000
526
+ ```
527
+
528
+ 4. Протестируйте:
529
+ ```bash
530
+ curl -X POST http://localhost:8000/analyze \
531
+ -H "Content-Type: application/json" \
532
+ -d '{"task": "Напишите функцию для суммы", "code": "def sum_list(numbers): return sum(numbers)"}'
533
+ ```
534
+
535
+ ---
536
+
537
+ **Готово!** Теперь модель интегрирована в ваш backend проект.
ENABLE_INFERENCE_API.md ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Как включить Inference API для модели
2
+
3
+ Для того чтобы на странице модели появилась кнопка "Inference API", нужно выполнить следующие шаги:
4
+
5
+ ## Шаг 1: Проверьте настройки модели
6
+
7
+ Убедитесь, что в `README.md` есть правильные метаданные:
8
+
9
+ ```yaml
10
+ ---
11
+ library_name: transformers
12
+ pipeline_tag: text-generation
13
+ inference: true
14
+ ---
15
+ ```
16
+
17
+ ✅ Эти настройки уже есть в вашей модели!
18
+
19
+ ## Шаг 2: Убедитесь, что модель публичная
20
+
21
+ 1. Перейдите на страницу модели: https://huggingface.co/Vilyam888/Code_analyze.1.0
22
+ 2. Нажмите на иконку настроек (⚙️) в правом верхнем углу
23
+ 3. Выберите "Settings" → "Change visibility"
24
+ 4. Убедитесь, что выбрано **"Public"**
25
+ 5. Сохраните изменения
26
+
27
+ ## Шаг 3: Подождите активации
28
+
29
+ После загрузки модели Inference API может активироваться автоматически, но это может занять:
30
+ - **Несколько минут** для небольших моделей
31
+ - **Несколько часов** для больших моделей (3B+ параметров)
32
+ - **До 24 часов** в некоторых случаях
33
+
34
+ ## Шаг 4: Проверьте статус Inference API
35
+
36
+ 1. Перейдите на страницу модели
37
+ 2. Прокрутите вниз до раздела **"Hosted inference API"**
38
+ 3. Если API активен, вы увидите:
39
+ - Кнопку "Use this model" → "Inference"
40
+ - Виджет для тестирования
41
+ - Информацию об API endpoint
42
+
43
+ ## Шаг 5: Если Inference API не активируется автоматически
44
+
45
+ Для моделей 3B+ параметров Inference API может быть недоступен бесплатно. В этом случае:
46
+
47
+ ### Вариант A: Запросить активацию (если доступно)
48
+
49
+ 1. Перейдите на https://huggingface.co/settings/billing
50
+ 2. Проверьте, есть ли у вас доступ к Inference API
51
+ 3. Если нет, может потребоваться подписка
52
+
53
+ ### Вариант B: Использовать Gradio Space (рекомендуется)
54
+
55
+ Создайте Gradio Space с API endpoint - это работает всегда:
56
+
57
+ 1. Создайте Space: https://huggingface.co/spaces
58
+ 2. Загрузите `app.py` и `requirements.txt`
59
+ 3. Используйте API endpoint: `https://YOUR_SPACE.hf.space/api/predict`
60
+
61
+ **Подробная инструкция:** См. `GRADIO_SPACE_INSTRUCTIONS.md`
62
+
63
+ ### Вариант C: Использовать модель локально
64
+
65
+ Пользователи могут загрузить модель и использовать локально:
66
+
67
+ ```python
68
+ from transformers import AutoModelForCausalLM, AutoTokenizer
69
+ # См. примеры в API_USAGE.md
70
+ ```
71
+
72
+ ## Текущий статус
73
+
74
+ Ваша модель уже настроена правильно:
75
+ - ✅ `pipeline_tag: text-generation` - установлен
76
+ - ✅ `inference: true` - включен
77
+ - ✅ Widget примеры - добавлены
78
+ - ✅ Публичная модель - должна быть
79
+
80
+ ## Что делать сейчас
81
+
82
+ 1. **Убедитесь, что модель публичная** (Settings → Change visibility → Public)
83
+ 2. **Загрузите обновленные файлы:**
84
+ ```bash
85
+ python scripts/upload_hf.py
86
+ ```
87
+ 3. **Подождите 1-24 часа** для активации Inference API
88
+ 4. **Проверьте страницу модели** - должна появиться кнопка "Inference"
89
+
90
+ ## Альтернатива: Gradio Space API
91
+
92
+ Если Inference API недоступен, используйте Gradio Space с API endpoint - это работает сразу и не требует ожидания.
93
+
94
+ **API Endpoint:** `https://YOUR_SPACE.hf.space/api/predict`
95
+
96
+ **Документация:** См. `API_ENDPOINT.md`
97
+
98
+ ---
99
+
100
+ **Примечание:** Для моделей размером 3B+ параметров Inference API может быть доступен только с подпиской или может не активироваться автоматически. В этом случае Gradio Space - лучшая альтернатива.
README.md CHANGED
@@ -1,68 +1,269 @@
1
- ---
2
- library_name: transformers
3
- license: apache-2.0
4
- base_model: Qwen/Qwen2.5-Coder-3B-Instruct
5
- pipeline_tag: text-generation
6
- inference: true
7
- tags:
8
- - code
9
- - code-analysis
10
- - qwen
11
- - qwen2
12
- - text-generation
13
- - transformers
14
- - fine-tuned
15
- widget:
16
- - text: "Проанализируй этот код:\ndef hello():\n print('Hello, World!')"
17
- example_title: "Анализ простого кода"
18
- - text: "Объясни, что делает эта функция:\ndef factorial(n):\n if n <= 1:\n return 1\n return n * factorial(n-1)"
19
- example_title: "Объяснение функции"
20
- ---
21
-
22
- # Code Analyzer Model
23
-
24
- Fine-tuned версия модели Qwen2.5-Coder-3B-Instruct для анализа кода студента на основе условия задачи.
25
-
26
- ## Описание модели
27
-
28
- Эта модель предназначена для анализа кода студента, нахождения слабых сильных сторон и выставления оценки. Модель принимает:
29
- - **Условие задачи** (текстовое описание)
30
- - **Код решения студента** (Python код)
31
-
32
- И возвращает детальный анализ в формате JSON, включающий:
33
- - Оценку правильности решения
34
- - Анализ соответствия требованиям задачи
35
- - Оценку качества кода
36
- - Сильные и слабые стороны решения
37
- - Рекомендации по улучшению
38
- - Детальный анализ с обоснованием
39
-
40
- Модель основана на Qwen2.5-Coder-3B-Instruct и дообучена с использованием LoRA (Low-Rank Adaptation).
41
-
42
-
43
-
44
-
45
- ## Детали обучения
46
-
47
- - **Базовая модель:** Qwen/Qwen2.5-Coder-3B-Instruct
48
- - **Метод обучения:** LoRA (Low-Rank Adaptation)
49
- - **Параметры LoRA:**
50
- - `r`: 16
51
- - `lora_alpha`: 32
52
- - `lora_dropout`: 0.05
53
- - **Фреймворк:** TRL (Transformer Reinforcement Learning)
54
- - **Формат данных:** JSONL с полями `input` и `output`
55
-
56
- ## Ограничения
57
-
58
- - Модель обучена на русском языке для анализа кода
59
- - Может генерировать неточные или неполные ответы
60
- - Требует GPU для эффективной работы
61
-
62
- ## Лицензия
63
-
64
- Apache 2.0
65
-
66
- ## Авторы
67
-
68
- Fine-tuned by Vilyam888
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ library_name: transformers
3
+ license: apache-2.0
4
+ base_model: Qwen/Qwen2.5-Coder-3B-Instruct
5
+ pipeline_tag: text-generation
6
+ inference: true
7
+ tags:
8
+ - code
9
+ - code-analysis
10
+ - qwen
11
+ - qwen2
12
+ - text-generation
13
+ - transformers
14
+ - fine-tuned
15
+ widget:
16
+ - text: "Задача:\nНапишите функцию, которая принимает список чисел и возвращает сумму всех элементов.\n\nРешение (код):\n```python\ndef sum_list(numbers):\n total = 0\n for num in numbers:\n total += num\n return total\n```\n\nОтвет:\n"
17
+ example_title: "Анализ кода - сумма списка"
18
+ - text: "Задача:\nСоздайте функцию для вычисления факториала числа.\n\nРешение (код):\n```python\ndef factorial(n):\n if n <= 1:\n return 1\n return n * factorial(n-1)\n```\n\nОтвет:\n"
19
+ example_title: "Анализ кода - факториал"
20
+ ---
21
+
22
+ # Code Analyzer Model
23
+
24
+ Fine-tuned версия модели Qwen2.5-Coder-3B-Instruct для анализа кода студента на основе условия задачи.
25
+
26
+ ## Описание модели
27
+
28
+ Эта модель была обучена на датасете ITOG для анализа кода студента. Модель принимает:
29
+ - **Условие задачи** (текстовое описание)
30
+ - **Код решения студента** (Python код)
31
+
32
+ И возвращает детальный анализ в формате JSON, включающий:
33
+ - Оценку правильности решения
34
+ - Анализ соответствия требованиям задачи
35
+ - Оценку качества кода
36
+ - Сильные и слабые стороны решения
37
+ - Рекомендации по улучшению
38
+ - Детальный анализ с обоснованием
39
+
40
+ Модель основана на Qwen2.5-Coder-3B-Instruct и дообучена с использованием LoRA (Low-Rank Adaptation).
41
+
42
+ ## Быстрый старт
43
+
44
+ ### Вариант 1: Использование Inference API (если доступен)
45
+
46
+ 1. Перейдите на страницу модели: https://huggingface.co/Vilyam888/Code_analyze.1.0
47
+ 2. Нажмите кнопку **"Use this model"** → **"Inference"**
48
+ 3. Или прокрутите вниз до раздела **"Hosted inference API"**
49
+ 4. Введите условие задачи и код студента в правильном формате
50
+ 5. Нажмите "Compute" для получения ответа
51
+
52
+ **Примечание:** Если кнопка "Inference" не появляется, см. `ENABLE_INFERENCE_API.md` для инструкций по активации.
53
+
54
+ ### Вариант 1.5: Создайте Gradio Space (если Inference API недоступен)
55
+
56
+ Если опция "Inference" не отображается в меню "Use this model", создайте интерактивный Gradio Space:
57
+
58
+ **Быстрая инструкция:**
59
+
60
+ 1. Перейдите на https://huggingface.co/spaces
61
+ 2. Нажмите **"Create new Space"**
62
+ 3. Заполните форму:
63
+ - **Space name**: `code-analyzer-demo` (или любое другое)
64
+ - **SDK**: выберите **Gradio**
65
+ - **Hardware**: **CPU Basic** (бесплатно)
66
+ - **Visibility**: **Public**
67
+ 4. Нажмите **"Create Space"**
68
+ 5. Загрузите файлы:
69
+ - `app.py` (из этой модели)
70
+ - `requirements_gradio.txt` → переименуйте в `requirements.txt`
71
+ 6. Дождитесь автоматического запуска (2-5 минут)
72
+ 7. Готово! Интерфейс будет доступен на странице Space
73
+
74
+ **Подробная инструкция:** См. файл `GRADIO_SPACE_INSTRUCTIONS.md` в корне проекта
75
+
76
+ ### Вариант 2: Использование локально (Python)
77
+
78
+ **Установка зависимостей:**
79
+ ```bash
80
+ pip install transformers torch
81
+ ```
82
+
83
+ **Простой пример использования:**
84
+ ```python
85
+ from transformers import AutoModelForCausalLM, AutoTokenizer
86
+ import torch
87
+ import json
88
+
89
+ model_name = "Vilyam888/Code_analyze.1.0"
90
+
91
+ # Загрузка модели
92
+ tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)
93
+ model = AutoModelForCausalLM.from_pretrained(
94
+ model_name,
95
+ torch_dtype=torch.bfloat16,
96
+ device_map="auto",
97
+ trust_remote_code=True
98
+ )
99
+
100
+ # Условие задачи
101
+ task = "Напишите функцию, которая принимает список чисел и возвращает сумму всех элементов."
102
+
103
+ # Код студента
104
+ code = """def sum_list(numbers):
105
+ total = 0
106
+ for num in numbers:
107
+ total += num
108
+ return total"""
109
+
110
+ # Форматирование входа
111
+ input_text = f"Задача:\n{task}\n\nРешение (код):\n```python\n{code}\n```"
112
+ prompt = f"{input_text}\n\nОтвет:\n"
113
+
114
+ # Генерация анализа
115
+ inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
116
+ with torch.no_grad():
117
+ outputs = model.generate(
118
+ **inputs,
119
+ max_new_tokens=1024,
120
+ temperature=0.7,
121
+ top_p=0.8,
122
+ top_k=20,
123
+ repetition_penalty=1.05,
124
+ do_sample=True
125
+ )
126
+
127
+ # Декодирование и парсинг JSON
128
+ response = tokenizer.decode(outputs[0], skip_special_tokens=True)
129
+ result = response.split("Ответ:")[-1].strip()
130
+ analysis = json.loads(result)
131
+
132
+ print(json.dumps(analysis, ensure_ascii=False, indent=2))
133
+ ```
134
+
135
+ **Или используйте готовые скрипты из репозитория:**
136
+
137
+ Простой пример (минимальный код):
138
+ ```bash
139
+ python scripts/quick_start_example.py
140
+ ```
141
+
142
+ Полный пример с интерактивным режимом:
143
+ ```bash
144
+ python scripts/use_model_example.py
145
+ ```
146
+
147
+ ## Использование
148
+
149
+ ### С помощью transformers
150
+
151
+ ```python
152
+ from transformers import AutoModelForCausalLM, AutoTokenizer
153
+ import torch
154
+
155
+ model_name = "Vilyam888/Code_analyze.1.0"
156
+
157
+ tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)
158
+ model = AutoModelForCausalLM.from_pretrained(
159
+ model_name,
160
+ torch_dtype=torch.bfloat16,
161
+ device_map="auto",
162
+ trust_remote_code=True
163
+ )
164
+
165
+ # Формат запроса
166
+ prompt = "Проанализируй этот код:\ndef hello():\n print('Hello, World!')"
167
+
168
+ # Форматирование в стиле обучения
169
+ text = f"{prompt}\n\nОтвет:\n"
170
+
171
+ inputs = tokenizer(text, return_tensors="pt").to(model.device)
172
+
173
+ with torch.no_grad():
174
+ outputs = model.generate(
175
+ **inputs,
176
+ max_new_tokens=512,
177
+ temperature=0.7,
178
+ top_p=0.8,
179
+ top_k=20,
180
+ repetition_penalty=1.05,
181
+ do_sample=True
182
+ )
183
+
184
+ response = tokenizer.decode(outputs[0], skip_special_tokens=True)
185
+ print(response)
186
+ ```
187
+
188
+ ### С помощью pipeline
189
+
190
+ ```python
191
+ from transformers import pipeline
192
+
193
+ model_name = "Vilyam888/Code_analyze.1.0"
194
+
195
+ generator = pipeline(
196
+ "text-generation",
197
+ model=model_name,
198
+ tokenizer=model_name,
199
+ trust_remote_code=True,
200
+ device_map="auto"
201
+ )
202
+
203
+ prompt = "Объясни, что делает этот код:\ndef factorial(n):\n if n <= 1:\n return 1\n return n * factorial(n-1)"
204
+ text = f"{prompt}\n\nОтвет:\n"
205
+
206
+ result = generator(
207
+ text,
208
+ max_new_tokens=512,
209
+ temperature=0.7,
210
+ top_p=0.8,
211
+ top_k=20,
212
+ repetition_penalty=1.05,
213
+ do_sample=True
214
+ )
215
+
216
+ print(result[0]["generated_text"])
217
+ ```
218
+
219
+ ## Детали обучения
220
+
221
+ - **Базовая модель:** Qwen/Qwen2.5-Coder-3B-Instruct
222
+ - **Метод обучения:** LoRA (Low-Rank Adaptation)
223
+ - **Параметры LoRA:**
224
+ - `r`: 16
225
+ - `lora_alpha`: 32
226
+ - `lora_dropout`: 0.05
227
+ - **Фреймворк:** TRL (Transformer Reinforcement Learning)
228
+ - **Формат данных:** JSONL с полями `input` и `output`
229
+
230
+ ## Ограничения
231
+
232
+ - Модель обучена на русском языке для анализа кода
233
+ - Может генерировать неточные или неполные ответы
234
+ - Требует GPU для эффективной работы
235
+
236
+ ## Использование через API
237
+
238
+ Модель можно использовать через несколько способов:
239
+
240
+ ### 1. Через transformers (Python)
241
+ ```python
242
+ from transformers import AutoModelForCausalLM, AutoTokenizer
243
+ # См. полные примеры в API_USAGE.md
244
+ ```
245
+
246
+ ### 2. Через Hugging Face Inference API
247
+ ```python
248
+ import requests
249
+ API_URL = "https://api-inference.huggingface.co/models/Vilyam888/Code_analyze.1.0"
250
+ # См. полные примеры в API_USAGE.md
251
+ ```
252
+
253
+ ### 3. Через Gradio Space API
254
+ Если создан Gradio Space, можно использовать его API endpoint.
255
+
256
+ ### 4. Интеграция в Backend проект
257
+ Примеры для FastAPI, Flask, Django, Node.js и других фреймворков.
258
+
259
+ **Подробная документация:**
260
+ - `API_USAGE.md` - использование через Hugging Face API
261
+ - `BACKEND_INTEGRATION.md` - интеграция в backend проекты
262
+
263
+ ## Лицензия
264
+
265
+ Apache 2.0
266
+
267
+ ## Авторы
268
+
269
+ Fine-tuned by Vilyam888
README_SPACE.md ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Как создать Gradio Space для интерактивного использования
2
+
3
+ Если опция "Inference" не появляется в меню "Use this model", создайте Gradio Space:
4
+
5
+ ## Шаг 1: Создайте новый Space на Hugging Face
6
+
7
+ 1. Перейдите на https://huggingface.co/spaces
8
+ 2. Нажмите "Create new Space"
9
+ 3. Заполните:
10
+ - **Space name**: `code-analyzer-demo` (или любое другое имя)
11
+ - **SDK**: выберите **Gradio**
12
+ - **Hardware**: выберите **CPU Basic** (бесплатно) или **GPU** (если доступно)
13
+ - **Visibility**: Public
14
+
15
+ ## Шаг 2: Загрузите файлы
16
+
17
+ Загрузите в Space следующие файлы:
18
+ - `app.py` (из этой папки)
19
+ - `requirements_gradio.txt` (переименуйте в `requirements.txt`)
20
+
21
+ ## Шаг 3: Дождитесь запуска
22
+
23
+ Space автоматически запустится и создаст интерактивный интерфейс для вашей модели!
24
+
25
+ ## Альтернатива: Используйте виджет на странице модели
26
+
27
+ На странице модели должен быть виджет внизу страницы, даже если опция "Inference" не в меню.
app.py CHANGED
@@ -1,176 +1,187 @@
1
- """
2
- Gradio Space для интерактивного использования модели Code Analyzer
3
- Модель анализирует код студента на основе условия задачи
4
- """
5
- import gradio as gr
6
- from transformers import AutoModelForCausalLM, AutoTokenizer
7
- import torch
8
- import json
9
-
10
- # Загрузка модели (будет выполнена при первом запуске)
11
- MODEL_NAME = "Vilyam888/Code_analyze.1.0"
12
-
13
- def load_model():
14
- """Загружает модель один раз при старте и сохраняет в глобальные переменные"""
15
- global model, tokenizer
16
-
17
- if model is None or tokenizer is None:
18
- print("Загрузка модели...")
19
- tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True)
20
- model = AutoModelForCausalLM.from_pretrained(
21
- MODEL_NAME,
22
- torch_dtype=torch.bfloat16 if torch.cuda.is_available() else torch.float32,
23
- device_map="auto",
24
- trust_remote_code=True
25
- )
26
- print("Модель загружена успешно!")
27
-
28
- # Глобальные переменные для модели
29
- model, tokenizer = None, None
30
-
31
- def build_input(task, code):
32
- """Форматирует вход в том же формате, что использовался при обучении"""
33
- parts = []
34
- if task.strip():
35
- parts.append(f"Задача:\n{task.strip()}")
36
- if code.strip():
37
- parts.append(f"Решение (код):\n```python\n{code.strip()}\n```")
38
- return "\n\n".join(parts)
39
-
40
- def analyze_code(task, code):
41
- """Анализирует код студента и возвращает результат в формате JSON"""
42
- global model, tokenizer
43
-
44
- if model is None or tokenizer is None:
45
- return "⏳ Загрузка модели... Пожалуйста, подождите."
46
-
47
- if not task.strip():
48
- return " Пожалуйста, введите условие задачи."
49
-
50
- if not code.strip():
51
- return "❌ Пожалуйста, введите код решения студента."
52
-
53
- try:
54
- # Форматирование входа в стиле обучения
55
- input_text = build_input(task, code)
56
- prompt = f"{input_text}\n\nОтвет:\n"
57
-
58
- # Токенизация
59
- inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
60
-
61
- # Генерация ответа
62
- with torch.no_grad():
63
- outputs = model.generate(
64
- **inputs,
65
- max_new_tokens=1024, # Увеличено для JSON ответа
66
- temperature=0.7,
67
- top_p=0.8,
68
- top_k=20,
69
- repetition_penalty=1.05,
70
- do_sample=True,
71
- pad_token_id=tokenizer.eos_token_id
72
- )
73
-
74
- # Декодирование ответа
75
- response = tokenizer.decode(outputs[0], skip_special_tokens=True)
76
-
77
- # Извлечение JSON ответа
78
- if "Ответ:" in response:
79
- json_str = response.split("Ответ:")[-1].strip()
80
- else:
81
- json_str = response
82
-
83
- # Попытка распарсить JSON
84
- try:
85
- result = json.loads(json_str)
86
- # Форматируем JSON для красивого отображения
87
- return json.dumps(result, ensure_ascii=False, indent=2)
88
- except json.JSONDecodeError:
89
- # Если не JSON, возвращаем как есть
90
- return json_str
91
-
92
- except Exception as e:
93
- return f"❌ Ошибка: {str(e)}"
94
-
95
- # Создание Gradio интерфейса
96
- with gr.Blocks(title="Code Analyzer Model") as demo:
97
- gr.Markdown("""
98
- # 🔍 Code Analyzer Model
99
-
100
- Модель для анализа кода студента на основе условия задачи.
101
-
102
- **Как использовать:**
103
- 1. Введите условие задачи в первое поле
104
- 2. Введите код решения студента во второе поле
105
- 3. Нажмите "Анализировать код"
106
- 4. Получите детальный анализ в формате JSON
107
- """)
108
-
109
- with gr.Row():
110
- with gr.Column():
111
- task_input = gr.Textbox(
112
- label="Условие задачи",
113
- placeholder="Введите условие задачи...",
114
- lines=5
115
- )
116
- code_input = gr.Textbox(
117
- label="Код решения студента",
118
- placeholder="Введите код решения...",
119
- lines=10
120
- )
121
- submit_btn = gr.Button("Анализировать код", variant="primary", size="lg")
122
-
123
- with gr.Column():
124
- result_output = gr.JSON(
125
- label="Результат анализа"
126
- )
127
- # Также показываем как текст для удобства копирования
128
- result_text = gr.Textbox(
129
- label="Результат (JSON текст)",
130
- lines=15,
131
- interactive=False
132
- )
133
-
134
- # Примеры
135
- gr.Examples(
136
- examples=[
137
- [
138
- "Напишите функцию, которая принимает список чисел и возвращает сумму всех элементов.",
139
- "def sum_list(numbers):\n total = 0\n for num in numbers:\n total += num\n return total"
140
- ],
141
- [
142
- "Создайте функцию для вычисления факториала числа.",
143
- "def factorial(n):\n if n <= 1:\n return 1\n return n * factorial(n-1)"
144
- ],
145
- ],
146
- inputs=[task_input, code_input]
147
- )
148
-
149
- def analyze_and_format(task, code):
150
- """Анализирует код и форматирует результат"""
151
- result_str = analyze_code(task, code)
152
- try:
153
- result_json = json.loads(result_str)
154
- return result_json, result_str
155
- except:
156
- return None, result_str
157
-
158
- # Загрузка модели при старте
159
- demo.load(load_model, outputs=None)
160
-
161
- # Обработчик кнопки
162
- submit_btn.click(
163
- fn=analyze_and_format,
164
- inputs=[task_input, code_input],
165
- outputs=[result_output, result_text]
166
- )
167
-
168
- # Обработчик Enter в поле кода
169
- code_input.submit(
170
- fn=analyze_and_format,
171
- inputs=[task_input, code_input],
172
- outputs=[result_output, result_text]
173
- )
174
-
175
- if __name__ == "__main__":
176
- demo.launch(theme=gr.themes.Soft())
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Gradio Space для интерактивного использования модели Code Analyzer
3
+ Модель анализирует код студента на основе условия задачи
4
+ Поддерживает как веб-интерфейс, так и API endpoint
5
+ """
6
+ import gradio as gr
7
+ from transformers import AutoModelForCausalLM, AutoTokenizer
8
+ import torch
9
+ import json
10
+ from pydantic import BaseModel
11
+ from typing import Optional
12
+
13
+ # Загрузка модели (будет выполнена при первом запуске)
14
+ MODEL_NAME = "Vilyam888/Code_analyze.1.0"
15
+
16
+ def load_model():
17
+ """Загружает модель один раз при старте и сохраняет в глобальные переменные"""
18
+ global model, tokenizer
19
+
20
+ if model is None or tokenizer is None:
21
+ print("Загрузка модели...")
22
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True)
23
+ model = AutoModelForCausalLM.from_pretrained(
24
+ MODEL_NAME,
25
+ torch_dtype=torch.bfloat16 if torch.cuda.is_available() else torch.float32,
26
+ device_map="auto",
27
+ trust_remote_code=True
28
+ )
29
+ print("Модель загружена успешно!")
30
+
31
+ # Глобальные переменные для модели
32
+ model, tokenizer = None, None
33
+
34
+ def build_input(task, code):
35
+ """Форматирует вход в том же формате, что использовался при обучении"""
36
+ parts = []
37
+ if task.strip():
38
+ parts.append(f"Задача:\n{task.strip()}")
39
+ if code.strip():
40
+ parts.append(f"Решение (код):\n```python\n{code.strip()}\n```")
41
+ return "\n\n".join(parts)
42
+
43
+ def analyze_code(task, code):
44
+ """Анализирует код студента и возвращает результат в формате JSON"""
45
+ global model, tokenizer
46
+
47
+ if model is None or tokenizer is None:
48
+ return " Загрузка модели... Пожалуйста, подождите."
49
+
50
+ if not task.strip():
51
+ return "❌ Пожалуйста, введите условие задачи."
52
+
53
+ if not code.strip():
54
+ return "❌ Пожалуйста, введите код решения студента."
55
+
56
+ try:
57
+ # Форматирование входа в стиле обучения
58
+ input_text = build_input(task, code)
59
+ prompt = f"{input_text}\n\nОтвет:\n"
60
+
61
+ # Токенизация
62
+ inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
63
+
64
+ # Генерация ответа
65
+ with torch.no_grad():
66
+ outputs = model.generate(
67
+ **inputs,
68
+ max_new_tokens=600, # Оптимизировано для CPU
69
+ temperature=0.7,
70
+ top_p=0.85,
71
+ top_k=20,
72
+ repetition_penalty=1.05,
73
+ do_sample=True,
74
+ pad_token_id=tokenizer.eos_token_id,
75
+ eos_token_id=tokenizer.eos_token_id
76
+ )
77
+
78
+ # Декодирование ответа
79
+ response = tokenizer.decode(outputs[0], skip_special_tokens=True)
80
+
81
+ # Извлечение JSON ответа
82
+ if "Ответ:" in response:
83
+ json_str = response.split("Ответ:")[-1].strip()
84
+ else:
85
+ json_str = response
86
+
87
+ # Попытка распарсить JSON
88
+ try:
89
+ result = json.loads(json_str)
90
+ # Форматируем JSON для красивого отображения
91
+ return json.dumps(result, ensure_ascii=False, indent=2)
92
+ except json.JSONDecodeError:
93
+ # Если не JSON, возвращаем как есть
94
+ return json_str
95
+
96
+ except Exception as e:
97
+ return f"❌ Ошибка: {str(e)}"
98
+
99
+ # Создание Gradio интерфейса
100
+ with gr.Blocks(title="Code Analyzer Model") as demo:
101
+ gr.Markdown("""
102
+ # 🔍 Code Analyzer Model
103
+
104
+ Модель для анализа кода студента на основе условия задачи.
105
+
106
+ **Как использовать:**
107
+ 1. Введите условие задачи в первое поле
108
+ 2. Введите код решения студента во второе поле
109
+ 3. Нажмите "Анализировать код"
110
+ 4. Получите детальный анализ в формате JSON
111
+
112
+ **API Endpoint:** `/api/predict` - используйте для интеграции в другие проекты
113
+ """)
114
+
115
+ with gr.Row():
116
+ with gr.Column():
117
+ task_input = gr.Textbox(
118
+ label="Условие задачи",
119
+ placeholder="Введите условие задачи...",
120
+ lines=5
121
+ )
122
+ code_input = gr.Textbox(
123
+ label="Код решения студента",
124
+ placeholder="Введите код решения...",
125
+ lines=10
126
+ )
127
+ submit_btn = gr.Button("Анализировать код", variant="primary", size="lg")
128
+
129
+ with gr.Column():
130
+ result_output = gr.JSON(
131
+ label="Результат анализа"
132
+ )
133
+ # Также показываем как текст для удобства копирования
134
+ result_text = gr.Textbox(
135
+ label="Результат (JSON текст)",
136
+ lines=15,
137
+ interactive=False
138
+ )
139
+
140
+ # Примеры
141
+ gr.Examples(
142
+ examples=[
143
+ [
144
+ "Напишите функцию, которая принимает список чисел и возвращает сумму всех элементов.",
145
+ "def sum_list(numbers):\n total = 0\n for num in numbers:\n total += num\n return total"
146
+ ],
147
+ [
148
+ "Создайте функцию для вычисления факториала числа.",
149
+ "def factorial(n):\n if n <= 1:\n return 1\n return n * factorial(n-1)"
150
+ ],
151
+ ],
152
+ inputs=[task_input, code_input]
153
+ )
154
+
155
+ def analyze_and_format(task, code):
156
+ """Анализирует код и форматирует результат"""
157
+ result_str = analyze_code(task, code)
158
+ try:
159
+ result_json = json.loads(result_str)
160
+ return result_json, result_str
161
+ except:
162
+ return None, result_str
163
+
164
+ # Загрузка модели при старте
165
+ demo.load(load_model, outputs=None)
166
+
167
+ # Обработчик кнопки
168
+ submit_btn.click(
169
+ fn=analyze_and_format,
170
+ inputs=[task_input, code_input],
171
+ outputs=[result_output, result_text]
172
+ )
173
+
174
+ # Обработчик Enter в поле кода
175
+ code_input.submit(
176
+ fn=analyze_and_format,
177
+ inputs=[task_input, code_input],
178
+ outputs=[result_output, result_text]
179
+ )
180
+
181
+ # Gradio автоматически создает API endpoint на /api/predict
182
+ # Для использования из других проектов:
183
+ # POST https://YOUR_SPACE_URL.hf.space/api/predict
184
+ # Body: {"data": ["task", "code"]}
185
+
186
+ if __name__ == "__main__":
187
+ demo.launch(theme=gr.themes.Soft(), server_name="0.0.0.0")
requirements_gradio.txt CHANGED
@@ -3,3 +3,5 @@ transformers>=5.0.0
3
  torch>=2.0.0
4
  accelerate
5
  sentencepiece
 
 
 
3
  torch>=2.0.0
4
  accelerate
5
  sentencepiece
6
+ fastapi>=0.104.0
7
+ uvicorn[standard]>=0.24.0