Upload folder using huggingface_hub
Browse files- API_ENDPOINT.md +279 -0
- API_USAGE.md +333 -0
- BACKEND_INTEGRATION.md +537 -0
- ENABLE_INFERENCE_API.md +100 -0
- README.md +269 -68
- README_SPACE.md +27 -0
- app.py +187 -176
- 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: "
|
| 17 |
-
example_title: "Анализ
|
| 18 |
-
- text: "
|
| 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 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
-
|
| 6 |
-
|
| 7 |
-
import
|
| 8 |
-
import
|
| 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 |
-
if
|
| 48 |
-
return "
|
| 49 |
-
|
| 50 |
-
if not
|
| 51 |
-
return "❌ Пожалуйста, введите
|
| 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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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
|