app.py 7.1 KB

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