Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto translation #10

Merged
merged 15 commits into from
Jun 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,7 @@ dmypy.json

# Pyre type checker
.pyre/
/server/miniconda/*
/tokenizers/*
/models/*
server_logs.text
5 changes: 3 additions & 2 deletions conda_config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ dependencies:
- python=3.9.7
- pip:
- websockets==10.0
- torch==1.10.1
- transformers==4.15
- torch==1.10.2
- transformers==4.16.2
- sentencepiece
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ pytorch==1.10.1
torchvision==0.11.2
cudatoolkit==11.3.1
websockets==10.0
transformers==4.10.2
transformers==4.16
10 changes: 7 additions & 3 deletions server/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@
#-- - Set HOST default value to 0.0.0.0
#--
#-- 25/03/2022 Lyaaaaa
#-- - Set LOG_FILEMODE default valie to 'a'
#-- - Set LOG_FILEMODE default value to 'a'
#--
#-- 21/05/2022 Lyaaaaa
#-- - Set LOG_FILEMODE default value to 'w'
#-- - Set LOG_LEVEL default value to DEBUG (Experimental branch only)
#---------------------------------------------------------------------------

import logging
Expand All @@ -32,5 +36,5 @@

# Logs
LOG_FILENAME = "server_logs.text"
LOG_FILEMODE = "a"
LOG_LEVEL = logging.INFO
LOG_FILEMODE = "w"
LOG_LEVEL = logging.DEBUG
47 changes: 47 additions & 0 deletions server/generator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#------------------------------------------------------------------------------
#-- Copyright (c) 2021-2022 LyaaaaaGames
#-- Copyright (c) 2022 AIdventure_Server contributors
#--
#-- Author : Lyaaaaaaaaaaaaaaa
#--
#-- Implementation Notes:
#-- - The class handling the text generation.
#--
#-- Anticipated changes:
#-- -
#--
#-- Changelog:
#-- - 18/02/2022 Lyaaaaa
#-- - Created the file.
#--
#-- - 22/05/2022 Lyaaaaa
#-- - Updated generate_text to support the gpu once again. Simplified the
#-- script by merging all the models input into a single dict "model_input".
#------------------------------------------------------------------------------

from model import Model

class Generator(Model):

#------------------------------------------------------------------------------
#-- generate_text
#------------------------------------------------------------------------------
def generate_text(self,
p_prompt = None,
p_context = None,
p_memory = None,
p_parameters = None):

model_input = p_memory + p_context + p_prompt
model_input = self._Tokenizer(model_input, return_tensors = "pt")

if self.is_gpu_enabled:
model_input.to("cuda")

p_parameters["max_length"] += len(model_input[0])

model_output = self._Model.generate(**model_input,
**p_parameters)
generated_text = self._Tokenizer.decode(model_output[0], skip_special_tokens=True)

return generated_text
103 changes: 34 additions & 69 deletions server/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@
#-- Author : Lyaaaaaaaaaaaaaaa
#--
#-- Portability Issues (feel free to remove this part if there is none):
#-- - Cuda might not be available depending of the environment and OS.
#-- - This class needs Pytorch installed.
#--
#-- Implementation Notes:
#-- - This class will handle all the task related to the AI model.
#--
#-- Anticipated changes:
#-- - Use a specific configuration.json file for each model (each model folder
#-- already has a config file. It could be more efficient to save each config
#-- into its own folder.
#-- - Update generate_text to make it possible to generate multiple answers.
#-- - Get rid of the configuration as I confused the generation and model config.
#--
#-- Changelog:
#-- - 31/08/2021 Lyaaaaa
Expand Down Expand Up @@ -77,20 +81,12 @@
#-- - Updated generate_text to append the input_ids' size to max_length in
#-- p_parameters. Also added attention_mask as parameter to generate method.
#--
#-- - 11/02/2022 Lyaaaaa
#-- - Removed _get_gpu_info call from generate_text method.
#-- - Updated _enable_gpu, _empty_gpu_cache and _get_gpu_info to fix the
#-- indentation.
#-- - Updated _enable_gpu to add a try except finally conditions to avoid
#-- to crash if the GPU runs out of memory.
#-- - Added a print in __init__ to investigate the ISSUE#2.
#-- - Replaced the prints by self._logger.info.
#--
#-- - 11/02/2022 Lyaaaaa
#-- - Updated _enable_gpu to call _model.to("cpu") if the the runtime error
#-- happens with the GPU.
#--
#-- - 18/02/2022 Lyaaaaa
#-- - Extracted generate_text method to generator class.
#-- - Added the model_type and AutoModelForSeq2SeqLM imports.
#-- - Updated __init__ to receive the a parameter to specify the model's type.
#-- - Updated _load and _download methods to use either AutoModelForCausalLM or
#-- AutoModelForSeq2SeqLM depending of the _model_type attribute's value.
#-- - Removed _Config and reload_config method (not used method)
#-- - Updated generate_text to fix the "inputs on different devices" error.
#-- attention_mark was not converted to cuda while model_input was.
Expand All @@ -111,27 +107,33 @@
#-- - Replaced self._logger by logger.log.
#------------------------------------------------------------------------------

from transformers import AutoModelForCausalLM, AutoTokenizer
from transformers import AutoModelForCausalLM, AutoModelForSeq2SeqLM, AutoTokenizer
from model_type import Model_Type
import os
import torch

# Custom imports
import logger

class Model():
_Tokenizer = AutoTokenizer
_Model = AutoModelForCausalLM

_Tokenizer : AutoTokenizer
_model_type : Model_Type
_Model = None

#------------------------------------------------------------------------------
#-- __init__
#------------------------------------------------------------------------------
def __init__(self, p_model_name = "EleutherAI/gpt-neo-125M", p_use_gpu = True):
def __init__(self,
p_model_name = "EleutherAI/gpt-neo-125M",
p_model_type = Model_Type.GENERATION.value,
p_use_gpu = True,):
self._tokenizer_path = "tokenizers/" + p_model_name
self._model_path = "models/" + p_model_name
self._model_name = p_model_name
self.is_cuda_available = torch.cuda.is_available()
self.is_gpu_enabled = False
self._model_type = p_model_type

if self._load() == False:
self._download()
Expand All @@ -140,52 +142,6 @@ def __init__(self, p_model_name = "EleutherAI/gpt-neo-125M", p_use_gpu = True):
else:
logger.log.info("Model successfully loaded from local file")


#------------------------------------------------------------------------------
#-- generate_text
#------------------------------------------------------------------------------
def generate_text(self,
p_prompt = None,
p_context = None,
p_memory = None,
p_parameters = None):

model_input = p_memory + p_context + p_prompt

model_input = p_memory + p_context + p_prompt
tokens = self._Tokenizer(model_input, return_tensors = "pt")
attention_mask = tokens.attention_mask
model_input = tokens.input_ids

p_parameters["max_length"] += len(model_input[0])

if self.is_gpu_enabled == True:
model_input = model_input.to("cuda")
attention_mask = attention_mask.to("cuda")
try:
model_output = self._Model.generate(input_ids = model_input,
attention_mask = attention_mask,
**p_parameters)
except Exception as error:
logger.log.error("Error while generating with the GPU:", error)
model_output = None
model_input = model_input.to("cpu")
attention_mask = attention_mask.to("cpu")
self._disable_gpu()

if self.is_gpu_enabled == False:
model_output = self._Model.generate(input_ids = model_input,
attention_mask = attention_mask,
**p_parameters)

generated_text = self._Tokenizer.decode(model_output[0], skip_special_tokens=True)

if self.is_gpu_enabled == True:
self._empty_gpu_cache()

return generated_text


#------------------------------------------------------------------------------
#-- _load
#------------------------------------------------------------------------------
Expand All @@ -198,9 +154,13 @@ def _load(self):
return False

try:
self._Model = AutoModelForCausalLM.from_pretrained(self._model_path)
if self._model_type == Model_Type.GENERATION.value:
self._Model = AutoModelForCausalLM.from_pretrained(self._model_path)
elif self._model_type == Model_Type.TRANSLATION.value:
self._Model = AutoModelForSeq2SeqLM.from_pretrained(self._model_path)

except:
except error:
logger.log.error(error)
return False

return True
Expand All @@ -224,9 +184,14 @@ def _download(self):
cache_dir = "cache",
resume_download = True)
logger.log.info("Trying to download the model...")
self._Model = AutoModelForCausalLM.from_pretrained(model_name,
cache_dir = "cache",
resume_download = True)
if self._model_type == Model_Type.GENERATION.value:
self._Model = AutoModelForCausalLM.from_pretrained(model_name,
cache_dir = "cache",
resume_download = True)
elif self._model_type == Model_Type.TRANSLATION.value:
self._Model = AutoModelForSeq2SeqLM.from_pretrained(model_name,
cache_dir = "cache",
resume_download = True)
self._save()


Expand Down
20 changes: 20 additions & 0 deletions server/model_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#------------------------------------------------------------------------------
#-- Copyright (c) 2021-2022 LyaaaaaGames
#-- Copyright (c) 2022 AIdventure_Server contributors
#--
#-- Author : Lyaaaaaaaaaaaaaaa
#--
#-- Implementation Notes:
#-- -
#-- Anticipated changes:
#-- -
#-- Changelog:
#-- - 18/02/2022 Lyaaaaa
#-- - Created the file
#------------------------------------------------------------------------------

from enum import Enum

class Model_Type(Enum):
GENERATION = 0
TRANSLATION = 1
4 changes: 4 additions & 0 deletions server/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
#--
#-- - 29/12/2021 Lyaaaaa
#-- - Added DOWNLOAD_MODEL and DOWNLOADED_MODEL requests.
#--
#-- - 01/03/2022 Lyaaaaa
#-- - Added TEXT_TRANSLATION request.
#------------------------------------------------------------------------------

from enum import Enum
Expand All @@ -38,3 +41,4 @@ class Request(Enum):
LOADED_MODEL = 4
DOWNLOAD_MODEL = 5
DOWNLOADED_MODEL = 6
TEXT_TRANSLATION = 7
Loading