File size: 6,713 Bytes
98a7a72 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
import logging
# Ленивая загрузка LLM
_generator = None
def load_model():
"""Ленивая загрузка модели"""
global _generator
if _generator is None:
try:
from transformers import pipeline
print('Загрузка LLM модели...')
_generator = pipeline('text2text-generation', model='cointegrated/rut5-base-multitask')
print('LLM модель загружена')
except Exception as e:
print(f'Ошибка загрузки LLM: {e}')
_generator = None
return _generator
def answer(question, context, system_prompt=None):
"""Генерирует ответ с помощью LLM"""
generator = load_model()
if not generator or not context:
return fallback_answer(context)
try:
# Формируем контекст
context_text = 'Доступные курсы:\n'
for i, course in enumerate(context[:6], 1):
context_text += f'{i}. {course["name"]} ({course["semester"]} семестр, {course["credits"]} кредитов)\n'
context_text += f' Описание: {course["short_desc"]}\n'
context_text += f' Теги: {", ".join(course["tags"])}\n\n'
# Системные инструкции
if system_prompt is None:
system_prompt = '''Ты помощник для абитуриентов магистратуры ITMO. Отвечай только по предоставленному контексту.
Если в контексте нет нужной информации — ответь: "в предоставленных данных об этом не сказано."
Отвечай кратко и по делу.
Не выдумывай факты и не давай общих ответов без ссылок на элементы контекста.'''
# Формируем промпт
prompt = f'''{system_prompt}
{context_text}
Вопрос: {question}'''
# Генерируем ответ
response = generator(
prompt,
max_new_tokens=180,
temperature=0.3,
do_sample=True
)[0]['generated_text']
return response.strip()
except Exception as e:
print(f'Ошибка генерации LLM: {e}')
return fallback_answer(context)
def fallback_answer(context):
"""Fallback ответ без LLM"""
if not context:
return 'В предоставленных данных об этом не сказано.'
courses = []
for item in context[:3]:
courses.append(f'{item["name"]} ({item["semester"]} семестр, {item["credits"]} кредитов)')
return f'Найденные курсы: {", ".join(courses)}.'
def generate_recommendations(courses, profile):
"""Генерирует рекомендации с помощью LLM"""
generator = load_model()
if not generator or not courses:
return fallback_recommendations(courses, profile)
try:
# Формируем контекст курсов
courses_text = 'Доступные курсы:\n'
for i, course in enumerate(courses[:7], 1):
courses_text += f'{i}. {course["name"]} ({course["credits"]} кредитов)\n'
courses_text += f' Сложность: {course.get("difficulty", "не указана")}, Теги: {", ".join(course["tags"])}\n'
courses_text += f' Описание: {course["short_desc"]}\n\n'
# Профиль студента
programming_exp = profile.get('programming_experience', 2)
math_level = profile.get('math_level', 2)
interests = profile.get('interests', [])
semester = profile.get('semester', 'не указан')
prompt = f'''Ты эксперт по выбору курсов. Дай персонализированные рекомендации студенту.
Профиль студента:
- Опыт программирования: {programming_exp}/5
- Уровень математики: {math_level}/4
- Интересы: {", ".join(interests)}
- Целевой семестр: {semester}
{courses_text}
Дай 5-7 лучших рекомендаций с объяснением почему они подходят. Учитывай уровень сложности и интересы. Отвечай кратко, по делу.'''
response = generator(
prompt,
max_new_tokens=300,
temperature=0.4,
do_sample=True
)[0]['generated_text']
return response.strip()
except Exception as e:
print(f'Ошибка генерации рекомендаций: {e}')
return fallback_recommendations(courses, profile)
def fallback_recommendations(courses, profile):
"""Fallback рекомендации без LLM"""
if not courses:
semester = profile.get('semester', 'не указан')
return f'Нет курсов для {semester} семестра.'
programming_exp = profile.get('programming_experience', 2)
math_level = profile.get('math_level', 2)
interests = profile.get('interests', [])
semester = profile.get('semester', 'не указан')
result = f'🎯 Рекомендации для {semester} семестра:\n\n'
for i, course in enumerate(courses[:7], 1):
result += f'{i}. {course["name"]} ({course["credits"]} кредитов)\n'
# Объяснение почему подходит
reasons = []
matching_tags = [tag for tag in interests if tag in course.get('tags', [])]
if matching_tags:
reasons.append(f'подходит по интересам: {", ".join(matching_tags)}')
if programming_exp <= 2 and 'python' in course.get('tags', []):
reasons.append('подходит для начинающих программистов')
elif programming_exp >= 4 and 'dl' in course.get('tags', []):
reasons.append('подходит для опытных программистов')
if math_level >= 2 and 'math' in course.get('tags', []):
reasons.append('требует хорошую математическую подготовку')
if reasons:
result += f' Почему подходит: {"; ".join(reasons)}\n'
result += '\n'
return result
|