QAway-to commited on
Commit
ac25eb6
·
1 Parent(s): b0e8bac

New model. Qwen/Qwen2.5-1.5B-Instruct. v1.1

Browse files
Files changed (1) hide show
  1. app.py +87 -57
app.py CHANGED
@@ -6,98 +6,128 @@ from transformers import (
6
  pipeline
7
  )
8
 
9
- # =========================================================
10
- # 1️⃣ Настройки моделей
11
- # =========================================================
 
 
12
  MBTI_MODEL = "f3nsmart/MBTIclassifier"
13
- INTERVIEWER_MODEL = "Phi-3-mini-128k-instruct"
 
 
 
14
 
15
- interviewer_tok = AutoTokenizer.from_pretrained(INTERVIEWER_MODEL)
16
- interviewer_model = AutoModelForCausalLM.from_pretrained(INTERVIEWER_MODEL)
17
- interviewer_pipe = pipeline(
 
 
 
 
 
18
  "text-generation",
19
- model=interviewer_model,
20
- tokenizer=interviewer_tok,
21
- max_new_tokens=80,
22
  temperature=0.7,
23
- top_p=0.9
24
  )
25
 
26
- # =========================================================
27
- # 2️⃣ Функции
28
- # =========================================================
29
- def generate_first_question():
30
- prompt = (
31
- "Begin a friendly MBTI-style conversation. "
32
- "Ask one simple, open-ended question about the person's interests or emotions. "
33
- "Do not mention that you are an AI or interviewer. Output only the question text."
34
- )
35
- q = interviewer_pipe(prompt)[0]["generated_text"].strip()
36
- return q.split("\n")[0] if "?" in q else "What makes you feel most fulfilled in your daily life?"
37
-
38
 
39
- def clean_question(text):
40
- """Удаляем мусор из вывода модели"""
 
 
41
  text = text.strip()
42
- for bad in ["You are", "instruction", "Generate", "MBTI", "task", "assistant:"]:
 
 
 
 
 
 
 
 
 
43
  if bad.lower() in text.lower():
44
- text = text.split(bad, 1)[-1]
45
- text = text.replace(":", "").replace("'", "").strip()
 
 
 
 
 
46
  if len(text.split()) < 3:
47
- return None
48
- return text
49
 
 
50
 
 
 
 
51
 
52
  def analyze_and_ask(user_text, prev_count):
 
 
 
53
  if not user_text.strip():
54
  return "⚠️ Введите ответ.", "", prev_count
55
 
 
56
  try:
57
  n = int(prev_count.split("/")[0]) + 1
58
  except Exception:
59
  n = 1
60
  counter = f"{n}/30"
61
 
 
62
  res = mbti_pipe(user_text)[0]
63
  res_sorted = sorted(res, key=lambda x: x["score"], reverse=True)
64
  mbti_text = "\n".join([f"{r['label']} → {r['score']:.3f}" for r in res_sorted[:3]])
65
 
 
66
  prompt = (
67
- f"The user said: '{user_text}'. "
68
- "Ask one short, open-ended follow-up question to learn more about their feelings, motivations, or habits. "
69
- "Avoid yes/no questions. Respond only with the question."
 
70
  )
71
- gen = interviewer_pipe(prompt)[0]["generated_text"].strip()
72
- question = gen.split("\n")[0]
73
- if not question.endswith("?"):
74
- question += "?"
 
75
  return mbti_text, question, counter
76
 
77
- # =========================================================
78
  # 3️⃣ Интерфейс Gradio
79
- # =========================================================
80
- with gr.Blocks(theme=gr.themes.Soft(), title="Adaptive MBTI Interviewer") as demo:
81
- gr.Markdown("## 🧠 Adaptive MBTI Interviewer\nОпредели личностный тип и получи следующий вопрос от интервьюера.")
 
 
 
 
82
 
83
  with gr.Row():
84
- with gr.Column(scale=2):
85
- inp = gr.Textbox(label="Ваш ответ", placeholder="Например: I enjoy working with people and organizing events.", lines=4)
 
 
 
 
86
  btn = gr.Button("Анализировать и задать новый вопрос", variant="primary")
 
 
 
 
87
 
88
- with gr.Column(scale=2):
89
- mbti_out = gr.Textbox(label="📊 Анализ MBTI", lines=5)
90
- question_out = gr.Textbox(label="💬 Следующий вопрос от интервьюера", lines=3)
91
- counter = gr.Textbox(label="Прогресс", value="0/30")
92
-
93
- # Первый вопрос при запуске
94
- demo.load(fn=generate_first_question, inputs=None, outputs=question_out)
95
 
96
- # Кнопка анализа и генерации
97
- btn.click(fn=analyze_and_ask, inputs=[inp, counter], outputs=[mbti_out, question_out, counter])
98
 
99
- # =========================================================
100
- # 4️⃣ Запуск
101
- # =========================================================
102
- if __name__ == "__main__":
103
- demo.launch()
 
6
  pipeline
7
  )
8
 
9
+ # ===============================================================
10
+ # 1️⃣ Настройки и модели
11
+ # ===============================================================
12
+
13
+ # Fine-tuned MBTI Classifier (твоя модель)
14
  MBTI_MODEL = "f3nsmart/MBTIclassifier"
15
+ mbti_pipe = pipeline("text-classification", model=MBTI_MODEL, return_all_scores=True)
16
+
17
+ # Модель-интервьюер
18
+ INTERVIEWER_MODEL = "Qwen/Qwen2.5-1.5B-Instruct"
19
 
20
+ tokenizer_qwen = AutoTokenizer.from_pretrained(INTERVIEWER_MODEL)
21
+ model_qwen = AutoModelForCausalLM.from_pretrained(
22
+ INTERVIEWER_MODEL,
23
+ torch_dtype="auto",
24
+ device_map="auto"
25
+ )
26
+
27
+ llm_pipe = pipeline(
28
  "text-generation",
29
+ model=model_qwen,
30
+ tokenizer=tokenizer_qwen,
31
+ max_new_tokens=70,
32
  temperature=0.7,
33
+ top_p=0.9,
34
  )
35
 
36
+ # ===============================================================
37
+ # 2️⃣ Вспомогательные функции
38
+ # ===============================================================
 
 
 
 
 
 
 
 
 
39
 
40
+ def clean_question(text: str) -> str:
41
+ """
42
+ Удаляет все инструкции и оставляет чистый вопрос.
43
+ """
44
  text = text.strip()
45
+
46
+ # Берём только первую строку, если LLM вдруг вывела много
47
+ text = text.split("\n")[0]
48
+
49
+ # Иногда Qwen вставляет кавычки — убираем
50
+ text = text.strip('"').strip("'")
51
+
52
+ # Если модель вывела "User:" / "Assistant:" / "Instruction:" и т.п.
53
+ bad_tokens = ["user:", "assistant:", "instruction", "interviewer", "system:"]
54
+ for bad in bad_tokens:
55
  if bad.lower() in text.lower():
56
+ text = text.split(bad)[-1].strip()
57
+
58
+ # Если вопрос не оканчивается знаком вопроса — добавляем
59
+ if "?" not in text:
60
+ text = text.rstrip(".") + "?"
61
+
62
+ # Мини-страховка от мусора
63
  if len(text.split()) < 3:
64
+ return "What do you usually enjoy doing in your free time?"
 
65
 
66
+ return text.strip()
67
 
68
+ def generate_first_question():
69
+ """Первый вопрос фиксированный (без ожидания генерации)"""
70
+ return "What do you usually enjoy doing in your free time?"
71
 
72
  def analyze_and_ask(user_text, prev_count):
73
+ """
74
+ Основная логика: анализ MBTI + генерация нового вопроса.
75
+ """
76
  if not user_text.strip():
77
  return "⚠️ Введите ответ.", "", prev_count
78
 
79
+ # Прогресс
80
  try:
81
  n = int(prev_count.split("/")[0]) + 1
82
  except Exception:
83
  n = 1
84
  counter = f"{n}/30"
85
 
86
+ # Анализ MBTI
87
  res = mbti_pipe(user_text)[0]
88
  res_sorted = sorted(res, key=lambda x: x["score"], reverse=True)
89
  mbti_text = "\n".join([f"{r['label']} → {r['score']:.3f}" for r in res_sorted[:3]])
90
 
91
+ # Промпт для Qwen — чёткий, чтобы не возвращала инструкцию
92
  prompt = (
93
+ f"User said: '{user_text}'.\n"
94
+ "Generate exactly one short, natural, open-ended question about personality, emotions, or preferences. "
95
+ "Avoid meta explanations, instructions, or introductions. "
96
+ "Output only the plain question text without quotes or notes."
97
  )
98
+
99
+ # Генерация нового вопроса
100
+ raw = llm_pipe(prompt)[0]["generated_text"]
101
+ question = clean_question(raw)
102
+
103
  return mbti_text, question, counter
104
 
105
+ # ===============================================================
106
  # 3️⃣ Интерфейс Gradio
107
+ # ===============================================================
108
+
109
+ with gr.Blocks(theme=gr.themes.Soft(), title="MBTI Personality Interviewer") as demo:
110
+ gr.Markdown(
111
+ "## 🧠 MBTI Personality Interviewer\n"
112
+ "Определи личностный тип и получи следующий вопрос от интервьюера."
113
+ )
114
 
115
  with gr.Row():
116
+ with gr.Column(scale=1):
117
+ inp = gr.Textbox(
118
+ label="Ваш ответ",
119
+ placeholder="Например: I enjoy working with people and organizing events.",
120
+ lines=4
121
+ )
122
  btn = gr.Button("Анализировать и задать новый вопрос", variant="primary")
123
+ with gr.Column(scale=1):
124
+ mbti_out = gr.Textbox(label="📊 Анализ MBTI", lines=4)
125
+ interviewer_out = gr.Textbox(label="💬 Следующий вопрос от интервьюера", lines=3)
126
+ progress = gr.Textbox(label="⏳ Прогресс", value="0/30")
127
 
128
+ btn.click(analyze_and_ask, inputs=[inp, progress], outputs=[mbti_out, interviewer_out, progress])
 
 
 
 
 
 
129
 
130
+ # Автоматическая загрузка первого вопроса
131
+ demo.load(lambda: ("", generate_first_question(), "0/30"), inputs=None, outputs=[mbti_out, interviewer_out, progress])
132
 
133
+ demo.launch()