OpenMotionLab/MotionGPT
118
1import os2os.system('pip install numpy==1.24.0')3os.system('pip install git+https://github.com/mattloper/chumpy')4os.system('pip install /home/user/app/pyrender')5os.system('pip install pyglet==1.4.0a1')6os.system('pip install triangle==20220202')7 8import gradio as gr9import torch10import time11import numpy as np12import pytorch_lightning as pl13import subprocess14from pathlib import Path15from mGPT.data.build_data import build_data16from mGPT.models.build_model import build_model17from mGPT.config import parse_args18from transformers import WhisperProcessor, WhisperForConditionalGeneration19import librosa20from huggingface_hub import snapshot_download21 22# Load model23cfg = parse_args(phase="webui") # parse config file24cfg.FOLDER = 'cache'25output_dir = Path(cfg.FOLDER)26output_dir.mkdir(parents=True, exist_ok=True)27pl.seed_everything(cfg.SEED_VALUE)28if torch.cuda.is_available():29 device = torch.device("cuda")30else:31 device = torch.device("cpu")32 33model_path = snapshot_download(repo_id="bill-jiang/MotionGPT-base")34 35datamodule = build_data(cfg, phase="test")36model = build_model(cfg, datamodule)37state_dict = torch.load(f'{model_path}/motiongpt_s3_h3d.tar',38 map_location="cpu")["state_dict"]39model.load_state_dict(state_dict)40model.to(device)41 42audio_processor = WhisperProcessor.from_pretrained(cfg.model.whisper_path)43audio_model = WhisperForConditionalGeneration.from_pretrained(44 cfg.model.whisper_path).to(device)45forced_decoder_ids_zh = audio_processor.get_decoder_prompt_ids(46 language="zh", task="translate")47forced_decoder_ids_en = audio_processor.get_decoder_prompt_ids(48 language="en", task="translate")49 50# HTML Style51Video_Components = """52<div class="side-video" style="position: relative;">53 <video width="340" autoplay loop>54 <source src="file/{video_path}" type="video/mp4">55 </video>56 <a class="videodl-button" href="file/{video_path}" download="{video_fname}" title="Download Video">57 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-video"><path d="m22 8-6 4 6 4V8Z"/><rect width="14" height="12" x="2" y="6" rx="2" ry="2"/></svg>58 </a>59 <a class="npydl-button" href="file/{motion_path}" download="{motion_fname}" title="Download Motion">60 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-file-box"><path d="M14.5 22H18a2 2 0 0 0 2-2V7.5L14.5 2H6a2 2 0 0 0-2 2v4"/><polyline points="14 2 14 8 20 8"/><path d="M2.97 13.12c-.6.36-.97 1.02-.97 1.74v3.28c0 .72.37 1.38.97 1.74l3 1.83c.63.39 1.43.39 2.06 0l3-1.83c.6-.36.97-1.02.97-1.74v-3.28c0-.72-.37-1.38-.97-1.74l-3-1.83a1.97 1.97 0 0 0-2.06 0l-3 1.83Z"/><path d="m7 17-4.74-2.85"/><path d="m7 17 4.74-2.85"/><path d="M7 17v5"/></svg>61 </a>62</div>63"""64 65Video_Components_example = """66<div class="side-video" style="position: relative;">67 <video width="340" autoplay loop controls>68 <source src="file/{video_path}" type="video/mp4">69 </video>70 <a class="npydl-button" href="file/{video_path}" download="{video_fname}" title="Download Video">71 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-video"><path d="m22 8-6 4 6 4V8Z"/><rect width="14" height="12" x="2" y="6" rx="2" ry="2"/></svg>72 </a>73</div>74"""75 76Text_Components = """77<h3 class="side-content" >{msg}</h3>78"""79 80 81def motion_token_to_string(motion_token, lengths, codebook_size=512):82 motion_string = []83 for i in range(motion_token.shape[0]):84 motion_i = motion_token[i].cpu(85 ) if motion_token.device.type == 'cuda' else motion_token[i]86 motion_list = motion_i.tolist()[:lengths[i]]87 motion_string.append(88 (f'<motion_id_{codebook_size}>' +89 ''.join([f'<motion_id_{int(i)}>' for i in motion_list]) +90 f'<motion_id_{codebook_size + 1}>'))91 return motion_string92 93 94def render_motion(data, feats, method='fast'):95 fname = time.strftime("%Y-%m-%d-%H_%M_%S", time.localtime(96 time.time())) + str(np.random.randint(10000, 99999))97 video_fname = fname + '.mp4'98 feats_fname = f"{fname}_feats" + '.npy'99 data_fname = f"{fname}_joints" + '.npy'100 output_npy_path = os.path.join(output_dir, feats_fname)101 output_joints_path = os.path.join(output_dir, data_fname)102 output_mp4_path = os.path.join(output_dir, video_fname)103 np.save(output_npy_path, feats)104 np.save(output_joints_path, data)105 106 render_cmd = ["python", "-m", "render", "--joints_path", output_joints_path, "--method", method, "--output_mp4_path", output_mp4_path, "--smpl_model_path", cfg.RENDER.SMPL_MODEL_PATH]107 os.system(" ".join(render_cmd))108 # subprocess.run(cmd3)109 110 return output_mp4_path, video_fname, output_npy_path, feats_fname111 112 113def load_motion(motion_uploaded, method):114 file = motion_uploaded['file']115 116 feats = torch.tensor(np.load(file), device=model.device)117 if len(feats.shape) == 2:118 feats = feats[None]119 # feats = model.datamodule.normalize(feats)120 121 # Motion tokens122 motion_lengths = feats.shape[0]123 motion_token, _ = model.vae.encode(feats)124 125 motion_token_string = model.lm.motion_token_to_string(126 motion_token, [motion_token.shape[1]])[0]127 motion_token_length = motion_token.shape[1]128 129 # Motion rendered130 joints = model.datamodule.feats2joints(feats.cpu()).cpu().numpy()131 output_mp4_path, video_fname, output_npy_path, joints_fname = render_motion(132 joints,133 feats.to('cpu').numpy(), method)134 135 motion_uploaded.update({136 "feats": feats,137 "joints": joints,138 "motion_video": output_mp4_path,139 "motion_video_fname": video_fname,140 "motion_joints": output_npy_path,141 "motion_joints_fname": joints_fname,142 "motion_lengths": motion_lengths,143 "motion_token": motion_token,144 "motion_token_string": motion_token_string,145 "motion_token_length": motion_token_length,146 })147 148 return motion_uploaded149 150 151def add_text(history, text, motion_uploaded, data_stored, method):152 data_stored = data_stored + [{'user_input': text}]153 154 text = f"""<h3>{text}</h3>"""155 history = history + [(text, None)]156 if 'file' in motion_uploaded.keys():157 motion_uploaded = load_motion(motion_uploaded, method)158 output_mp4_path = motion_uploaded['motion_video']159 video_fname = motion_uploaded['motion_video_fname']160 output_npy_path = motion_uploaded['motion_joints']161 joints_fname = motion_uploaded['motion_joints_fname']162 history = history + [(Video_Components.format(163 video_path=output_mp4_path,164 video_fname=video_fname,165 motion_path=output_npy_path,166 motion_fname=joints_fname), None)]167 168 return history, gr.update(value="",169 interactive=False), motion_uploaded, data_stored170 171 172def add_audio(history, audio_path, data_stored, language='en'):173 audio, sampling_rate = librosa.load(audio_path, sr=16000)174 input_features = audio_processor(175 audio, sampling_rate, return_tensors="pt"176 ).input_features # whisper training sampling rate, do not modify177 input_features = torch.Tensor(input_features).to(device)178 179 if language == 'English':180 forced_decoder_ids = forced_decoder_ids_en181 else:182 forced_decoder_ids = forced_decoder_ids_zh183 predicted_ids = audio_model.generate(input_features,184 forced_decoder_ids=forced_decoder_ids)185 text_input = audio_processor.batch_decode(predicted_ids,186 skip_special_tokens=True)187 text_input = str(text_input).strip('[]"')188 data_stored = data_stored + [{'user_input': text_input}]189 gr.update(value=data_stored, interactive=False)190 history = history + [(text_input, None)]191 192 return history, data_stored193 194 195def add_file(history, file, txt, motion_uploaded):196 motion_uploaded['file'] = file.name197 txt = txt.replace(" <Motion_Placeholder>", "") + " <Motion_Placeholder>"198 return history, gr.update(value=txt, interactive=True), motion_uploaded199 200 201def bot(history, motion_uploaded, data_stored, method):202 203 motion_length, motion_token_string = motion_uploaded[204 "motion_lengths"], motion_uploaded["motion_token_string"]205 206 input = data_stored[-1]['user_input']207 prompt = model.lm.placeholder_fulfill(input, motion_length,208 motion_token_string, "")209 data_stored[-1]['model_input'] = prompt210 batch = {211 "length": [motion_length],212 "text": [prompt],213 }214 215 outputs = model(batch, task="t2m")216 out_feats = outputs["feats"][0]217 out_lengths = outputs["length"][0]218 out_joints = outputs["joints"][:out_lengths].detach().cpu().numpy()219 out_texts = outputs["texts"][0]220 output_mp4_path, video_fname, output_npy_path, joints_fname = render_motion(221 out_joints,222 out_feats.to('cpu').numpy(), method)223 224 motion_uploaded = {225 "feats": None,226 "joints": None,227 "motion_video": None,228 "motion_lengths": 0,229 "motion_token": None,230 "motion_token_string": '',231 "motion_token_length": 0,232 }233 234 data_stored[-1]['model_output'] = {235 "feats": out_feats,236 "joints": out_joints,237 "length": out_lengths,238 "texts": out_texts,239 "motion_video": output_mp4_path,240 "motion_video_fname": video_fname,241 "motion_joints": output_npy_path,242 "motion_joints_fname": joints_fname,243 }244 245 if '<Motion_Placeholder>' == out_texts:246 response = [247 Video_Components.format(video_path=output_mp4_path,248 video_fname=video_fname,249 motion_path=output_npy_path,250 motion_fname=joints_fname)251 ]252 elif '<Motion_Placeholder>' in out_texts:253 response = [254 Text_Components.format(255 msg=out_texts.split("<Motion_Placeholder>")[0]),256 Video_Components.format(video_path=output_mp4_path,257 video_fname=video_fname,258 motion_path=output_npy_path,259 motion_fname=joints_fname),260 Text_Components.format(261 msg=out_texts.split("<Motion_Placeholder>")[1]),262 ]263 else:264 response = f"""<h3>{out_texts}</h3>"""265 266 history[-1][1] = ""267 for character in response:268 history[-1][1] += character269 time.sleep(0.02)270 yield history, motion_uploaded, data_stored271 272 273def bot_example(history, responses):274 history = history + responses275 return history276 277 278with open("assets/css/custom.css", "r", encoding="utf-8") as f:279 customCSS = f.read()280 281with gr.Blocks(css=customCSS) as demo:282 283 # Examples284 chat_instruct = gr.State([285 (None,286 "π Hi, I'm MotionGPT! I can generate realistic human motion from text, or generate text from motion."287 ),288 (None,289 "π‘ You can chat with me in pure text like generating human motion following your descriptions."290 ),291 (None,292 "π‘ After generation, you can click the button in the top right of generation human motion result to download the human motion video or feature stored in .npy format."293 ),294 (None,295 "π‘ With the human motion feature file downloaded or got from dataset, you are able to ask me to translate it!"296 ),297 (None,298 "π‘ Of courser, you can also purely chat with me and let me give you human motion in text, here are some examples!"299 ),300 (None,301 "π‘ We provide two motion visulization methods. The default fast method is skeleton line ploting which is like the examples below:"302 ),303 (None,304 Video_Components_example.format(305 video_path="assets/videos/example0_fast.mp4",306 video_fname="example0_fast.mp4")),307 (None,308 "π‘ And the slow method is SMPL model rendering which is more realistic but slower."309 ),310 (None,311 Video_Components_example.format(312 video_path="assets/videos/example0.mp4",313 video_fname="example0.mp4")),314 (None,315 "π‘ If you want to get the video in our paper and website like below, you can refer to the scirpt in our [github repo](https://github.com/OpenMotionLab/MotionGPT#-visualization)."316 ),317 (None,318 Video_Components_example.format(319 video_path="assets/videos/example0_blender.mp4",320 video_fname="example0_blender.mp4")),321 (None, "π Follow the examples and try yourself!"),322 ])323 chat_instruct_sum = gr.State([(None, '''324 π Hi, I'm MotionGPT! I can generate realistic human motion from text, or generate text from motion.325 326 1. You can chat with me in pure text like generating human motion following your descriptions.327 2. After generation, you can click the button in the top right of generation human motion result to download the human motion video or feature stored in .npy format.328 3. With the human motion feature file downloaded or got from dataset, you are able to ask me to translate it!329 4. Of course, you can also purely chat with me and let me give you human motion in text, here are some examples!330 ''')] + chat_instruct.value[-7:])331 332 t2m_examples = gr.State([333 (None,334 "π‘ You can chat with me in pure text, following are some examples of text-to-motion generation!"335 ),336 ("A person is walking forwards, but stumbles and steps back, then carries on forward.",337 Video_Components_example.format(338 video_path="assets/videos/example0.mp4",339 video_fname="example0.mp4")),340 ("Generate a man aggressively kicks an object to the left using his right foot.",341 Video_Components_example.format(342 video_path="assets/videos/example1.mp4",343 video_fname="example1.mp4")),344 ("Generate a person lowers their arms, gets onto all fours, and crawls.",345 Video_Components_example.format(346 video_path="assets/videos/example2.mp4",347 video_fname="example2.mp4")),348 ("Show me the video of a person bends over and picks things up with both hands individually, then walks forward.",349 Video_Components_example.format(350 video_path="assets/videos/example3.mp4",351 video_fname="example3.mp4")),352 ("Imagine a person is practing balancing on one leg.",353 Video_Components_example.format(354 video_path="assets/videos/example5.mp4",355 video_fname="example5.mp4")),356 ("Show me a person walks forward, stops, turns directly to their right, then walks forward again.",357 Video_Components_example.format(358 video_path="assets/videos/example6.mp4",359 video_fname="example6.mp4")),360 ("I saw a person sits on the ledge of something then gets off and walks away.",361 Video_Components_example.format(362 video_path="assets/videos/example7.mp4",363 video_fname="example7.mp4")),364 ("Show me a person is crouched down and walking around sneakily.",365 Video_Components_example.format(366 video_path="assets/videos/example8.mp4",367 video_fname="example8.mp4")),368 ])369 370 m2t_examples = gr.State([371 (None,372 "π‘ With the human motion feature file downloaded or got from dataset, you are able to ask me to translate it, here are some examples!"373 ),374 ("Please explain the movement shown in <Motion_Placeholder> using natural language.",375 None),376 (Video_Components_example.format(377 video_path="assets/videos/example0.mp4",378 video_fname="example0.mp4"),379 "The person was pushed but didn't fall down"),380 ("What kind of action is being represented in <Motion_Placeholder>? Explain it in text.",381 None),382 (Video_Components_example.format(383 video_path="assets/videos/example4.mp4",384 video_fname="example4.mp4"),385 "The figure has its hands curled at jaw level, steps onto its left foot and raises right leg with bent knee to kick forward and return to starting stance."386 ),387 ("Provide a summary of the motion demonstrated in <Motion_Placeholder> using words.",388 None),389 (Video_Components_example.format(390 video_path="assets/videos/example2.mp4",391 video_fname="example2.mp4"),392 "A person who is standing with his arms up and away from his sides bends over, gets down on his hands and then his knees and crawls forward."393 ),394 ("Generate text for <Motion_Placeholder>:", None),395 (Video_Components_example.format(396 video_path="assets/videos/example5.mp4",397 video_fname="example5.mp4"),398 "The man tries to stand in a yoga tree pose and looses his balance."),399 ("Provide a summary of the motion depicted in <Motion_Placeholder> using language.",400 None),401 (Video_Components_example.format(402 video_path="assets/videos/example6.mp4",403 video_fname="example6.mp4"),404 "Person walks up some steps then leeps to the other side and goes up a few more steps and jumps dow"405 ),406 ("Describe the motion represented by <Motion_Placeholder> in plain English.",407 None),408 (Video_Components_example.format(409 video_path="assets/videos/example7.mp4",410 video_fname="example7.mp4"),411 "Person sits down, then stands up and walks forward. then the turns around 180 degrees and walks the opposite direction"412 ),413 ("Provide a description of the action in <Motion_Placeholder> using words.",414 None),415 (Video_Components_example.format(416 video_path="assets/videos/example8.mp4",417 video_fname="example8.mp4"),418 "This man is bent forward and walks slowly around."),419 ])420 421 t2t_examples = gr.State([422 (None,423 "π‘ Of course, you can also purely chat with me and let me give you human motion in text, here are some examples!"424 ),425 ('Depict a motion as like you have seen it.',426 "A person slowly walked forward in rigth direction while making the circle"427 ),428 ('Random say something about describing a human motion.',429 "A man throws punches using his right hand."),430 ('Describe the motion of someone as you will.',431 "Person is moving left to right in a dancing stance swaying hips, moving feet left to right with arms held out"432 ),433 ('Come up with a human motion caption.',434 "A person is walking in a counter counterclockwise motion."),435 ('Write a sentence about how someone might dance.',436 "A person with his hands down by his sides reaches down for something with his right hand, uses the object to make a stirring motion, then places the item back down."437 ),438 ('Depict a motion as like you have seen it.',439 "A person is walking forward a few feet, then turns around, walks back, and continues walking."440 )441 ])442 443 Init_chatbot = chat_instruct.value[:444 1] + t2m_examples.value[:445 3] + m2t_examples.value[:3] + t2t_examples.value[:2] + chat_instruct.value[446 -7:]447 448 # Variables449 motion_uploaded = gr.State({450 "feats": None,451 "joints": None,452 "motion_video": None,453 "motion_lengths": 0,454 "motion_token": None,455 "motion_token_string": '',456 "motion_token_length": 0,457 })458 data_stored = gr.State([])459 460 gr.Markdown('''461# MotionGPT: Human Motion as a Foreign Language462 463<div>464<a style="display:inline-block" href="https://motion-gpt.github.io/"><img src='https://img.shields.io/badge/Project_page-9375A7'></a>465<a style="display:inline-block; margin-left: .5em" href="https://arxiv.org/abs/2306.14795"><img src="https://img.shields.io/badge/2306.14795-f9f7f7?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADcAAABMCAYAAADJPi9EAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAuIwAALiMBeKU/dgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAa2SURBVHja3Zt7bBRFGMAXUCDGF4rY7m7bAwuhlggKStFgLBgFEkCIIRJEEoOBYHwRFYKilUgEReVNJEGCJJpehHI3M9vZvd3bUP1DjNhEIRQQsQgSHiJgQZ5dv7krWEvvdmZ7d7vHJN+ft/f99pv5XvOtJMFCqvoCUpTdIEeRLC+L9Ox5i3Q9LACaCeK0kXoSChVcD3C/tQPHpAEsquQ73IkUcEz2kcLCknyGW5MGjkljRFVL8xJOKyi4CwCOuQAeAkfTP1+tNxLkogvgEbDgffkJqKqvuMA5ifOpqg/5qWecRstNg7xoUTI1Fovdxg8oy2s5AP8CGeYHmGngeZaOL4I4LXLcpHg4149/GDz4xqgsb+UAbMKKUpkrqHA43MUyyJpWUK0EHeG2YKRXr7tB+QMcgGewLD+ebTDbtrtbBt7UPlhS4rV4IvcDI7J8P1OeA/AcAI7LHljN7aB8XTowJmZt9EFRD/o0SDMH4HlwMhMyDWZZSAHFf3YDs3RS49WDLuaAY3IJq+qzmQKLxXAZKN7oDoYbdV3v5elPqiSpMyiOuAEVZVqHXb1OhloUH+MA+ztO0cAO/RkrfyBE7OAEbAZvO8vzVtTRWFD6DAfY5biBM3PWiaL0a4lvXICwnV8WjmE6ntYmhqX2jjp5LbMZjCw/wbYeN6CizOa2GMVzQOlmHjB4Ceuyk6LJ8huccEmR5Xddg7OOV/NAtchW+E3XbOag60QA4Qwuarca0bRuEJyr+cFQwzcY98huxhAKdQelt4kAQpj4qJ3gvFXAYn+aJumXk1yPlpQUgtIHhbYoFMUstNRRWgjnpl4A7IKlayNymqFHFaWCpV9CFry3LGxR1CgA5kB5M8OX2goApwpaz6mdOMGxtAgXWJySxb4WuQD4qTDgU+N5AAnzpr7ChSWpCyisiQJqY0Y7FtmSKpbV23b45kC0KHBxcQ9QeI8w4KgnHRPVtIU7rOtbioLVg5Hl/qDwSVFAMqLSMSObroCdZYlzIJtMRFVHCaRo/wFWPgaAXzdbBpkc2A4aKzCNd97+URQuESYGDDhIVfWOQIKZJu4D2+oXlgDTV1865gUQZDts756BArMNMoR1oa46BYqbyPixZz1ZUFV3sgwoGBajuBKATl3btIn8QYYMuezRgrsiRUWyr2BxA40EkPMpA/Hm6gbUu7fjEXA3azP6AsbKD9bxdUuhjM9W7fII52BF+daRpE4+WA3P501+jbfmHvQKyFqMuXf7Ot4mkN2fr50y+bRH61X7AXdUpHSxaPQ4GVbR5AGw3g+434XgQGKfr72I+vQRhfsu92dOx7WicInzt3CBg1RVpMm0NveWo2SqFzgmdNZMbriILD+S+zoueWf2vSdAipzacWN5nMl6XxNlUHa/J8DoJodUDE0HR8Ll5V0lPxcrLEHZPV4AzS83OLis7FowVa3RSku7BSNxJqQAlN3hBTC2apmDSkpaw22wJemGQFUG7J4MlP3JC6A+f96V7vRyX9It3nzT/GrjIU8edM7rMSnIi10f476lzbE1K7yEiEuWro0OJBguLCwDuFOJc1Na6sRWL/cCeMIwUN9ggSVbe3v/5/EgzTKWLvEAiBrYRUkgwNI2ZaFQNT75UDxEUEx97zYnzpmiLEmbaYCbNxYtFAb0/Z4AztgUrhyxuNgxPnhfHFDHz/vTgFWUQZxTRkkJhQ6YNdVUEPAfO6ZV5BRss6LcCVb7VaAma9giy0XJZBt9IQh42NY0NSdgbLIPlLUF6rEdrdt0CUCK1wsCbkcI3ZSLc7ZSwGLbmJXbPsNxnE5xilYKAobZ77LpGZ8TAIun+/iCKQoF71IxQDI3K2CCd+ARNvXg9sykBcnHAoCZG4u66hlDoQLe6QV4CRtFSxZQ+D0BwNO2jgdkzoGoah1nj3FVlSR19taTSYxI8QLut23U8dsgzqHulJNCQpcqBnpTALCuQ6NSYLHpmR5i42gZzuIdcrMMvMJbQlxe3jXxyZnLACl7ARm/FjPIDOY8ODtpM71sxwfcZpvBeUzKWmfNINM5AS+wO0Khh7dMqKccu4+qatarZjYAwDlgetzStHtEt+XedsBOQtU9XMrRgjg4KTnc5nr+dmqadit/4C4uLm8DuA9koJTj1TL7fI5nDL+qqoo/FLGAzL7dYT17PzvAcQONYSUQRxW/QMrHZVIyik0ZuQA2mzp+Ji8BW4YM3Mbzm9inaHkJCGfrUZZjujiYailfFwA8DHIy3acwUj4v9vUVa+SmgNsl5fuyDTKovW9/IAmfLV0Pi2UncA515kjYdrwC9i9rpuHiq3JwtAAAAABJRU5ErkJggg=="></a>466<a style="display:inline-block; margin-left: .5em" href='https://github.com/OpenMotionLab/MotionGPT'><img src='https://img.shields.io/github/stars/OpenMotionLab/MotionGPT?style=social'/></a>467<a style="display:inline-block; margin-left: .5em" href="https://github.com/OpenMotionLab/MotionGPT#-citation"><img src="https://img.shields.io/badge/Citation-4385FE?&logo=google-scholar&logoColor=white" alt="Citation"> </a>468</div>469 470 ''')471 472 chatbot = gr.Chatbot(Init_chatbot,473 elem_id="mGPT",474 height=600,475 label="MotionGPT",476 avatar_images=(None,477 ("assets/images/avatar_bot.jpg")),478 bubble_full_width=False)479 480 with gr.Row():481 with gr.Column(scale=0.85):482 with gr.Row():483 txt = gr.Textbox(484 label="Text",485 show_label=False,486 elem_id="textbox",487 placeholder=488 "Enter text and press ENTER or speak to input. You can also upload motion.",489 container=False)490 491 with gr.Row():492 aud = gr.Audio(sources=["microphone"],493 label="Speak input",494 type='filepath')495 btn = gr.UploadButton("π Upload motion",496 elem_id="upload",497 file_types=["file"])498 # regen = gr.Button("π Regenerate", elem_id="regen")499 clear = gr.ClearButton([txt, chatbot, aud], value='ποΈ Clear')500 501 with gr.Row():502 gr.Markdown('''503 ### You can get more examples (pre-generated for faster response) by clicking the buttons below:504 ''')505 506 with gr.Row():507 instruct_eg = gr.Button("Instructions", elem_id="instruct")508 t2m_eg = gr.Button("Text-to-Motion", elem_id="t2m")509 m2t_eg = gr.Button("Motion-to-Text", elem_id="m2t")510 t2t_eg = gr.Button("Random description", elem_id="t2t")511 512 with gr.Column(scale=0.15, min_width=150):513 method = gr.Dropdown(["slow", "fast"],514 label="Visulization method",515 interactive=True,516 elem_id="method",517 value="slow")518 519 language = gr.Dropdown(["English", "δΈζ"],520 label="Speech language",521 interactive=True,522 elem_id="language",523 value="English")524 525 txt_msg = txt.submit(526 add_text, [chatbot, txt, motion_uploaded, data_stored, method],527 [chatbot, txt, motion_uploaded, data_stored],528 queue=False).then(bot, [chatbot, motion_uploaded, data_stored, method],529 [chatbot, motion_uploaded, data_stored])530 531 txt_msg.then(lambda: gr.update(interactive=True), None, [txt], queue=False)532 533 file_msg = btn.upload(add_file, [chatbot, btn, txt, motion_uploaded],534 [chatbot, txt, motion_uploaded],535 queue=False)536 aud_msg = aud.stop_recording(537 add_audio, [chatbot, aud, data_stored, language],538 [chatbot, data_stored],539 queue=False).then(bot, [chatbot, motion_uploaded, data_stored, method],540 [chatbot, motion_uploaded, data_stored])541 # regen_msg = regen.click(bot,542 # [chatbot, motion_uploaded, data_stored, method],543 # [chatbot, motion_uploaded, data_stored],544 # queue=False)545 546 instruct_msg = instruct_eg.click(bot_example, [chatbot, chat_instruct_sum],547 [chatbot],548 queue=False)549 t2m_eg_msg = t2m_eg.click(bot_example, [chatbot, t2m_examples], [chatbot],550 queue=False)551 m2t_eg_msg = m2t_eg.click(bot_example, [chatbot, m2t_examples], [chatbot],552 queue=False)553 t2t_eg_msg = t2t_eg.click(bot_example, [chatbot, t2t_examples], [chatbot],554 queue=False)555 556 chatbot.change(scroll_to_output=True)557 558if __name__ == "__main__":559 demo.launch(debug=True, allowed_paths=["."])560 