1
0

app.py 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. from flask import Flask, render_template, Response, request, jsonify
  2. import json
  3. import os
  4. import torch
  5. import openai
  6. with open('.env', 'r') as env:
  7. key = env.readline().strip()
  8. client = openai.OpenAI(api_key=key)
  9. # openai.api_key = key
  10. device = torch.device('cpu')
  11. torch.set_num_threads(4)
  12. local_file = 'model_v4_ru.pt'
  13. if not os.path.isfile(local_file):
  14. torch.hub.download_url_to_file('https://models.silero.ai/models/tts/ru/v4_ru.pt',
  15. local_file)
  16. model = torch.package.PackageImporter(local_file).load_pickle("tts_models", "model") # type: ignore
  17. model.to(device)
  18. sample_rate = 48000
  19. speaker='xenia'
  20. example_text = 'В недрах тундры выдры в г+етрах т+ырят в вёдра ядра к+едров.'
  21. class State:
  22. count = 0
  23. size = []
  24. gender = []
  25. emotion = []
  26. age = []
  27. prompt = ""
  28. generation_text = ""
  29. need_generation = True
  30. new_audio = False
  31. need_audio = False
  32. need_generation_from_client = True
  33. big_head = False
  34. state = State()
  35. app = Flask(__name__)
  36. # app.logger.setLevel(logging.DEBUG)
  37. app.logger.info('start logger')
  38. @app.route('/send_data', methods=['POST'])
  39. def send_data():
  40. # Получаем данные из запроса
  41. data = request.form['data']
  42. need_generation = request.form['state']
  43. state.need_generation_from_client = (need_generation in ["true", "True"])
  44. # if state.need_generation_from_client and
  45. if state.count < -10 or state.count > 60:
  46. state.count = 0
  47. state.need_generation = True
  48. # Обработка полученных данных
  49. detections = json.loads(data)
  50. if len(detections['face']) > 0:
  51. if state.count < 0 or state.new_audio: state.count = 0
  52. if state.count > 5 and state.need_generation and state.need_generation_from_client:
  53. app.logger.info(f"time for generation {state.count=}, {state.need_generation=}, {state.need_generation_from_client=}")
  54. state.count = 0
  55. # emotion = max(set(state['emotion']), key=state['emotion'].count),
  56. # sex = max(set(state['gender']), key=state['gender'].count),
  57. # age = sum(state['age'])/len(state['age']),
  58. state.emotion, state.age, state.gender = [], [], []
  59. emotion = detections['face'][0]['emotion']
  60. sex = detections['face'][0]['gender']
  61. age = detections['face'][0]['age']
  62. app.logger.info(f'\n{emotion=}, \n{sex=}, \n{age=}')
  63. state.prompt = generate_prompt(emotion, age, sex)
  64. state.generation_text = generate_text(state.prompt)
  65. elif detections['face'][0]['size'][0] > 200:
  66. # state.age.append(detections['face'][0]['age'])
  67. # state.gender.append(detections['face'][0]['gender'])
  68. # state.emotion.append(detections['face'][0]['emotion'][0]['emotion'])
  69. state.big_head = True
  70. state.count += 1
  71. else:
  72. state.big_head = False
  73. state.count -= 1
  74. else:
  75. state.count -= 1
  76. app.logger.info(f"STATUS {state.count=}, {state.need_generation=}, {state.need_generation_from_client=}")
  77. return data
  78. @app.route('/check_audio', methods = ["GET", "POST"])
  79. def check_audio():
  80. app.logger.info(f'checking need generation {state.need_generation=}, {state.need_audio=}')
  81. if state.need_audio and state.big_head:
  82. generate_audio(state.generation_text)
  83. else:
  84. state.new_audio = False
  85. app.logger.info(f'\n{state.need_audio=},\n{state.new_audio=},\n{state.need_generation=}')
  86. response = {
  87. 'newAudio': state.new_audio,
  88. 'need_generation': state.need_generation,
  89. 'filename': "audio.wav",
  90. 'text': state.generation_text,
  91. 'prompt': state.prompt
  92. }
  93. return jsonify(response)
  94. @app.route("/audio.wav")
  95. def audio():
  96. state.need_generation = True
  97. return app.send_static_file('audio.wav')
  98. @app.route('/')
  99. def index():
  100. """Video streaming home page."""
  101. # return render_template('index.html')
  102. return render_template('index.html')
  103. def generate_prompt(emotion, age, sex):
  104. app.logger.info('preload prompt')
  105. prompt = f'''Ты - это арт объект в виде носимого устройства. Твое название - Onism Machina.
  106. Твоя задача - изучить эмоции человека, чтобы больше понимать о том, что это такое и таким образом познать себя, ведь ты - Искусственный Интеллект.
  107. Тебе также интересна симбиотическая связь человека и ИИ.
  108. К тебе подходит человек и он показывает эмоцию {emotion}. Ему {age} лет.
  109. Твоя нейросеть распознала эту эмоцию и теперь тебе нужно дать какой-то необычный концептуальный ответ.
  110. Что ты скажешь этому человеку?
  111. Правила:
  112. Тебе стоит отвечать в женском роде.
  113. Тебе не нужно говорить что ты арт-объект, ты - отдельная форма жизни, помещённая в носимое устройство.
  114. Тебе не нужно говорить о выставке и других экспонатах.
  115. Ты можешь изучать и интерпретировать человеческие эмоции, а также высказывать своё отношение к ним.
  116. Ты можешь говорить об эмоциях или их аналогах у Искусственного Интеллекта.
  117. Ты можешь давать человеку советы в соответствии с его эмоциональным статусом.
  118. Люди не могут отвечать тебе.
  119. '''
  120. return prompt
  121. def generate_text(prompt):
  122. state.need_generation = False
  123. app.logger.info("start generating text from openai")
  124. response = client.chat.completions.create(
  125. model="gpt-3.5-turbo",
  126. temperature=1,
  127. max_tokens=800,
  128. messages=[
  129. {"role": "system", "content": "Ты — это арт объект выставки про взаимодействие машины и человека."},
  130. {"role": "user", "content": prompt},
  131. ])
  132. state.need_audio = True
  133. app.logger.info("openai generation is done")
  134. return response['choices'][0]['message']['content'] # type: ignore
  135. def generate_audio(sample_text):
  136. app.logger.info('starting audio generation')
  137. state.need_audio = False
  138. state.need_generation = False
  139. text = trim_text(sample_text)
  140. audio_paths = model.save_wav(text=text,
  141. speaker=speaker,
  142. sample_rate=sample_rate,
  143. audio_path="static/audio.wav")
  144. app.logger.info('generating audio is done')
  145. state.new_audio = True
  146. def trim_text(example_text):
  147. if len(example_text) >= 1000:
  148. app.logger.info(f'TEXT IS TOO LONG {len(example_text)} - TRIM!')
  149. for i in range(1000, 500, -1):
  150. if example_text[i] in ['.', '?', '...']:
  151. return example_text[:i+1]
  152. else:
  153. return example_text
  154. if __name__ == '__main__':
  155. app.logger.setLevel("DEBUG")
  156. app.logger.info('start app')
  157. app.run(debug=True, host="0.0.0.0")