alvaroalon2 commited on
Commit
c39d1b7
·
1 Parent(s): de14bd5

feat: parameterized models

Browse files
CHANGELOG.md CHANGED
@@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
 
8
 
 
 
 
 
9
  ## [0.1.0] - 2024-04-09
10
 
11
  - First commit
 
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
 
8
 
9
+ ## [0.1.1] - 2024-05-18
10
+
11
+ - Parameterized models, now is possible to make use of new OpenAI models like gpt-4o
12
+
13
  ## [0.1.0] - 2024-04-09
14
 
15
  - First commit
README.md CHANGED
@@ -133,7 +133,21 @@ license: cc-by-nd-4.0
133
 
134
  <img src="./docs/images/header.png" alt="LingAIcoach" width="1000" style="display: block; margin: 0 auto"/>
135
 
136
- Yo can access to the App through: [LinguAIcoach Web](https://linguaicoach.streamlit.app/)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
 
138
  ## Description
139
  LinguAIcoach is a project that helps to improve your English with the assistance of AI. It provides tools for practicing, testing, and learning English using AI chatbots and other language processing technologies. The LinguAIcoach project utilizes DALL-E, GPT-4V, Whisper and GPT models to enhance English language learning in a multimodal way. The project offers a variety of exercises to enhance your English skills. The exercises cover different types of exams.
 
133
 
134
  <img src="./docs/images/header.png" alt="LingAIcoach" width="1000" style="display: block; margin: 0 auto"/>
135
 
136
+ You can access to the App through Streamlit share: [LinguAIcoach Web](https://linguaicoach.streamlit.app/) or through Huggingface Spaces: [LinguAIcoach](https://huggingface.co/spaces/alvaroalon2/linguAIcoach)
137
+
138
+ ## Table of Contents
139
+
140
+ - [Recent Activities](#recent-activities)
141
+ - [Description](#description)
142
+ - [Installation](#installation)
143
+ - [Usage](#usage)
144
+ - [Contributing](#contributing)
145
+ - [License](#license)
146
+ - [Authors](#authors)
147
+ - [Next Steps](#next-steps)
148
+
149
+ ## Recent Activities
150
+ - Parameterized models, now is possible to make use of new OpenAI models like gpt-4o.
151
 
152
  ## Description
153
  LinguAIcoach is a project that helps to improve your English with the assistance of AI. It provides tools for practicing, testing, and learning English using AI chatbots and other language processing technologies. The LinguAIcoach project utilizes DALL-E, GPT-4V, Whisper and GPT models to enhance English language learning in a multimodal way. The project offers a variety of exercises to enhance your English skills. The exercises cover different types of exams.
poetry.lock CHANGED
The diff for this file is too large to render. See raw diff
 
pyproject.toml CHANGED
@@ -1,6 +1,6 @@
1
  [tool.poetry]
2
  name = "LinguAIcoach"
3
- version = "0.1.0"
4
  description = "Help to improve your English with AI"
5
  authors = ["alvaroalon2"]
6
  readme = "README.md"
 
1
  [tool.poetry]
2
  name = "LinguAIcoach"
3
+ version = "0.1.1"
4
  description = "Help to improve your English with AI"
5
  authors = ["alvaroalon2"]
6
  readme = "README.md"
src/config.json CHANGED
@@ -3,5 +3,18 @@
3
  "N_MAX_RETRY": 3,
4
  "OPENAI_TEMPERATURE_GEN": 0.8,
5
  "OPENAI_TEMPERATURE_EVAL": 0.3,
6
- "IMG_GEN_SIZE": "256x256"
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  }
 
3
  "N_MAX_RETRY": 3,
4
  "OPENAI_TEMPERATURE_GEN": 0.8,
5
  "OPENAI_TEMPERATURE_EVAL": 0.3,
6
+ "IMG_PROMPT_TEMPERATURE": 0.3,
7
+ "IMG_GEN_SIZE": "256x256",
8
+ "EVALUATION_MODEL": {
9
+ "img_desc": {
10
+ "temperature": 0.3,
11
+ "model": "gpt-4o"
12
+ },
13
+ "qa": {
14
+ "temperature": 0.3,
15
+ "model": "gpt-4o"
16
+ }
17
+ },
18
+ "MODEL_TEXT_GEN": "gpt-4o",
19
+ "MODEL_IMG_PROMPT": "gpt-4o"
20
  }
src/main.py CHANGED
@@ -80,11 +80,16 @@ if not st.session_state.openai_api_key:
80
  st.info("Please add your OpenAI API key to continue.")
81
  st.stop()
82
 
 
 
 
83
  model_eval = model_factory.create_model(
84
  model_class=st.session_state["exam_type"],
85
  openai_api_key=st.session_state.openai_api_key,
86
  level=level,
87
  chat_temperature=config["OPENAI_TEMPERATURE_EVAL"],
 
 
88
  )
89
 
90
  generator = gen_factory.create_model(
@@ -94,6 +99,10 @@ generator = gen_factory.create_model(
94
  level=level,
95
  description=exam_desc,
96
  chat_temperature=config["OPENAI_TEMPERATURE_GEN"],
 
 
 
 
97
  history_chat=[
98
  AIMessage(content=f"Previous question (Don't repeat): {q.content}")
99
  for q in st.session_state["question"][-config["N_MAX_HISTORY"] :]
 
80
  st.info("Please add your OpenAI API key to continue.")
81
  st.stop()
82
 
83
+ eval_model = config["EVALUATION_MODEL"][st.session_state["exam_type"]]["model"]
84
+ eval_temperature = config["EVALUATION_MODEL"][st.session_state["exam_type"]]["temperature"]
85
+
86
  model_eval = model_factory.create_model(
87
  model_class=st.session_state["exam_type"],
88
  openai_api_key=st.session_state.openai_api_key,
89
  level=level,
90
  chat_temperature=config["OPENAI_TEMPERATURE_EVAL"],
91
+ eval_model=eval_model,
92
+ eval_temperature=eval_temperature,
93
  )
94
 
95
  generator = gen_factory.create_model(
 
99
  level=level,
100
  description=exam_desc,
101
  chat_temperature=config["OPENAI_TEMPERATURE_GEN"],
102
+ n_messages_memory=config["N_MAX_HISTORY"],
103
+ chat_model=config["MODEL_TEXT_GEN"],
104
+ prompt_model=config["MODEL_IMG_PROMPT"],
105
+ prompt_model_temperature=config["IMG_PROMPT_TEMPERATURE"],
106
  history_chat=[
107
  AIMessage(content=f"Previous question (Don't repeat): {q.content}")
108
  for q in st.session_state["question"][-config["N_MAX_HISTORY"] :]
src/models/{lc_base_model.py → base/base_model.py} RENAMED
@@ -10,11 +10,28 @@ from langchain_openai import ChatOpenAI
10
 
11
  class ChainGenerator(ABC):
12
 
13
- def __init__(self, openai_api_key: SecretStr, chat_temperature: float = 0.3) -> None:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  self.openai_api_key = openai_api_key
15
  self.chat_temperature = chat_temperature
16
 
17
- self._initialize_chat_llm()
18
 
19
  @abstractmethod
20
  def _get_system_prompt(self) -> ChatPromptTemplate:
@@ -32,12 +49,12 @@ class ChainGenerator(ABC):
32
  RunnableSequence: Chain.
33
  """
34
 
35
- def _initialize_chat_llm(self) -> None:
36
  """Initializes the ChatOpenAI language model."""
37
  self.chat_llm = ChatOpenAI(
38
  api_key=self.openai_api_key,
39
  temperature=self.chat_temperature,
40
- model="gpt-3.5-turbo-1106",
41
  )
42
 
43
 
@@ -49,6 +66,11 @@ class EvaluationChatModel(ChainGenerator):
49
 
50
  Args:
51
  level (str): Level of the exam.
 
 
 
 
 
52
  """
53
  super().__init__(openai_api_key=openai_api_key, chat_temperature=chat_temperature)
54
  self.level = level
 
10
 
11
  class ChainGenerator(ABC):
12
 
13
+ def __init__(
14
+ self,
15
+ openai_api_key: SecretStr,
16
+ chat_temperature: float = 0.3,
17
+ chat_model: str = "gpt-3.5-turbo",
18
+ ) -> None:
19
+ """
20
+ Initializes the class with the given parameters.
21
+
22
+ Args:
23
+ openai_api_key (SecretStr): The API key for OpenAI.
24
+ chat_temperature (float, optional): The temperature to use for chat. Defaults to 0.3.
25
+ chat_model (str, optional): The model to use for chat. Defaults to "gpt-3.5-turbo".
26
+
27
+ Returns:
28
+ None
29
+
30
+ """
31
  self.openai_api_key = openai_api_key
32
  self.chat_temperature = chat_temperature
33
 
34
+ self._initialize_chat_llm(chat_model)
35
 
36
  @abstractmethod
37
  def _get_system_prompt(self) -> ChatPromptTemplate:
 
49
  RunnableSequence: Chain.
50
  """
51
 
52
+ def _initialize_chat_llm(self, chat_model: str) -> None:
53
  """Initializes the ChatOpenAI language model."""
54
  self.chat_llm = ChatOpenAI(
55
  api_key=self.openai_api_key,
56
  temperature=self.chat_temperature,
57
+ model=chat_model,
58
  )
59
 
60
 
 
66
 
67
  Args:
68
  level (str): Level of the exam.
69
+ openai_api_key (SecretStr): OpenAI API key.
70
+ chat_temperature (float): Temperature for the chat model.
71
+
72
+ Returns:
73
+ None
74
  """
75
  super().__init__(openai_api_key=openai_api_key, chat_temperature=chat_temperature)
76
  self.level = level
src/models/{lc_img_desc_model.py → evaluator/img_evaluator.py} RENAMED
@@ -6,10 +6,9 @@ from langchain.schema import HumanMessage
6
  from langchain_core.output_parsers import StrOutputParser
7
  from langchain_core.pydantic_v1 import BaseModel, Field, SecretStr
8
  from langchain_openai import ChatOpenAI
 
9
  from typing_extensions import override
10
 
11
- from src.models.lc_qa_model import EvaluationChatModelQA
12
-
13
 
14
  class EvaluationChatModelImg(EvaluationChatModelQA):
15
 
@@ -29,8 +28,30 @@ class EvaluationChatModelImg(EvaluationChatModelQA):
29
  description="Example of a response based on the AI image description following the given guidelines (just if there is)",
30
  )
31
 
32
- def __init__(self, level: str, openai_api_key: SecretStr, chat_temperature: float = 0.3) -> None:
33
- self.gpt4v = ChatOpenAI(temperature=0.3, model="gpt-4-vision-preview", max_tokens=1024, api_key=openai_api_key)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  super().__init__(level, openai_api_key=openai_api_key, chat_temperature=chat_temperature)
35
 
36
  def _get_system_prompt(self) -> ChatPromptTemplate:
@@ -74,7 +95,7 @@ class EvaluationChatModelImg(EvaluationChatModelQA):
74
 
75
  multi_chain_dict.update(
76
  {
77
- "ai_img_desc": itemgetter("image_url") | self.gpt4v | StrOutputParser(),
78
  "base_response": itemgetter("base_response"),
79
  }
80
  )
@@ -93,7 +114,7 @@ class EvaluationChatModelImg(EvaluationChatModelQA):
93
  Dict: The output of the prediction.
94
  """
95
  input_model = self.Input(user_desc=user_desc, image_url=image_url)
96
- gpt4v_input = [
97
  HumanMessage(
98
  content=[
99
  {"type": "text", "text": "What is this image showing?"},
@@ -105,6 +126,6 @@ class EvaluationChatModelImg(EvaluationChatModelQA):
105
  )
106
  ]
107
  result = self.chain.invoke(
108
- {"base_response": input_model.user_desc, "image_url": gpt4v_input}, config=self.config
109
  )
110
  return result.dict(by_alias=True)
 
6
  from langchain_core.output_parsers import StrOutputParser
7
  from langchain_core.pydantic_v1 import BaseModel, Field, SecretStr
8
  from langchain_openai import ChatOpenAI
9
+ from src.models.evaluator.text_evaluator import EvaluationChatModelQA
10
  from typing_extensions import override
11
 
 
 
12
 
13
  class EvaluationChatModelImg(EvaluationChatModelQA):
14
 
 
28
  description="Example of a response based on the AI image description following the given guidelines (just if there is)",
29
  )
30
 
31
+ def __init__(
32
+ self,
33
+ eval_model: str,
34
+ level: str,
35
+ openai_api_key: SecretStr,
36
+ chat_temperature: float = 0.3,
37
+ eval_temperature: float = 0.3,
38
+ ) -> None:
39
+ """
40
+ Initializes the class with the given parameters.
41
+
42
+ Args:
43
+ eval_model (str): The vision model to use for image description.
44
+ level (str): The level of the exam.
45
+ openai_api_key (SecretStr): The API key for OpenAI.
46
+ chat_temperature (float, optional): The temperature to use for chat. Defaults to 0.3.
47
+ eval_temperature (float, optional): The temperature to use for image model. Defaults to 0.3.
48
+
49
+ Returns:
50
+ None
51
+ """
52
+ self.vision_model = ChatOpenAI(
53
+ temperature=eval_temperature, model=eval_model, max_tokens=1024, api_key=openai_api_key
54
+ )
55
  super().__init__(level, openai_api_key=openai_api_key, chat_temperature=chat_temperature)
56
 
57
  def _get_system_prompt(self) -> ChatPromptTemplate:
 
95
 
96
  multi_chain_dict.update(
97
  {
98
+ "ai_img_desc": itemgetter("image_url") | self.vision_model | StrOutputParser(),
99
  "base_response": itemgetter("base_response"),
100
  }
101
  )
 
114
  Dict: The output of the prediction.
115
  """
116
  input_model = self.Input(user_desc=user_desc, image_url=image_url)
117
+ vision_model_input = [
118
  HumanMessage(
119
  content=[
120
  {"type": "text", "text": "What is this image showing?"},
 
126
  )
127
  ]
128
  result = self.chain.invoke(
129
+ {"base_response": input_model.user_desc, "image_url": vision_model_input}, config=self.config
130
  )
131
  return result.dict(by_alias=True)
src/models/{lc_qa_model.py → evaluator/text_evaluator.py} RENAMED
@@ -9,8 +9,7 @@ from langchain.prompts import ChatPromptTemplate, PromptTemplate
9
  from langchain_core.pydantic_v1 import BaseModel, Field, SecretStr
10
  from langchain_core.runnables import Runnable, RunnableConfig
11
  from langchain_openai import ChatOpenAI
12
-
13
- from src.models.lc_base_model import EvaluationChatModel
14
 
15
  logger = logging.getLogger(__name__)
16
 
@@ -60,7 +59,14 @@ class EvaluationChatModelQA(EvaluationChatModel):
60
  default="",
61
  )
62
 
63
- def __init__(self, level: str, openai_api_key: SecretStr, chat_temperature: float = 0.3) -> None:
 
 
 
 
 
 
 
64
  """
65
  Initializes the class with the given parameters.
66
 
@@ -68,13 +74,16 @@ class EvaluationChatModelQA(EvaluationChatModel):
68
  exam_prompt (str): The prompt for the exam.
69
  level (str): The level of the exam.
70
  openai_api_key (SecretStr): The API key for OpenAI.
 
 
 
71
 
72
  Returns:
73
  None
74
  """
75
  super().__init__(level=level, openai_api_key=openai_api_key, chat_temperature=chat_temperature)
76
 
77
- self.checker_llm = ChatOpenAI(api_key=self.openai_api_key, temperature=0, model="gpt-3.5-turbo")
78
  self.prompt = self._get_system_prompt()
79
 
80
  self.chain = self._create_chain()
 
9
  from langchain_core.pydantic_v1 import BaseModel, Field, SecretStr
10
  from langchain_core.runnables import Runnable, RunnableConfig
11
  from langchain_openai import ChatOpenAI
12
+ from src.models.base.base_model import EvaluationChatModel
 
13
 
14
  logger = logging.getLogger(__name__)
15
 
 
59
  default="",
60
  )
61
 
62
+ def __init__(
63
+ self,
64
+ level: str,
65
+ openai_api_key: SecretStr,
66
+ eval_model: str = "gpt-3.5-turbo",
67
+ chat_temperature: float = 0.3,
68
+ eval_temperature: float = 0.3,
69
+ ) -> None:
70
  """
71
  Initializes the class with the given parameters.
72
 
 
74
  exam_prompt (str): The prompt for the exam.
75
  level (str): The level of the exam.
76
  openai_api_key (SecretStr): The API key for OpenAI.
77
+ eval_model (str, optional): The model to use for evaluation. Defaults to "gpt-3.5-turbo".
78
+ chat_temperature (float, optional): The temperature to use for chat. Defaults to 0.3.
79
+ eval_temperature (float, optional): The temperature to use for evaluation. Defaults to 0.3.
80
 
81
  Returns:
82
  None
83
  """
84
  super().__init__(level=level, openai_api_key=openai_api_key, chat_temperature=chat_temperature)
85
 
86
+ self.checker_llm = ChatOpenAI(api_key=self.openai_api_key, temperature=eval_temperature, model=eval_model)
87
  self.prompt = self._get_system_prompt()
88
 
89
  self.chain = self._create_chain()
src/models/gen/img_generator.py ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Any
2
+
3
+ from langchain.prompts import ChatPromptTemplate, PromptTemplate
4
+ from langchain_community.utilities.dalle_image_generator import DallEAPIWrapper
5
+ from langchain_core.output_parsers import StrOutputParser
6
+ from langchain_core.pydantic_v1 import SecretStr
7
+ from langchain_core.runnables import Runnable
8
+ from langchain_openai import ChatOpenAI
9
+ from src.models.base.base_model import ContentGenerator
10
+
11
+
12
+ class ImgGenerator(ContentGenerator):
13
+
14
+ def __init__( # noqa: PLR0913
15
+ self,
16
+ exam_prompt: str,
17
+ level: str,
18
+ description: str,
19
+ openai_api_key: SecretStr,
20
+ chat_model: str = "gpt-3.5-turbo",
21
+ prompt_model: str = "gpt-3.5-turbo",
22
+ chat_temperature: float = 0.3,
23
+ prompt_model_temperature: float = 0.3,
24
+ img_size: str = "256x256",
25
+ ) -> None:
26
+ """
27
+ Initializes the class with the exam prompt, level, description, OpenAI API key, and optional image size.
28
+
29
+ Parameters:
30
+ exam_prompt (str): The prompt for the exam.
31
+ level (str): The level of the exam.
32
+ description (str): Description of the exam.
33
+ openai_api_key (SecretStr): The OpenAI API key.
34
+ chat_model (str, optional): The model to use for chat. Defaults to "gpt-3.5-turbo".
35
+ prompt_model (str, optional): The model to use for prompting img. Defaults to "gpt-3.5-turbo".
36
+ chat_temperature (float, optional): The temperature to use for chat. Defaults to 0.3.
37
+ prompt_model_temperature (float, optional): The temperature to use for prompting img. Defaults to 0.3.
38
+ img_size (str, optional): The size of the image. Default is "256x256".
39
+
40
+ Returns:
41
+ None
42
+ """
43
+ super().__init__(openai_api_key, chat_temperature, chat_model)
44
+ self.level = level
45
+ self.exam_prompt = exam_prompt
46
+ self.description = description
47
+ self.dalle = DallEAPIWrapper(
48
+ size=img_size, api_key=self.openai_api_key.get_secret_value()
49
+ ) # type: ignore[call-arg]
50
+ self.img_prompt_model = ChatOpenAI(
51
+ model=prompt_model, temperature=prompt_model_temperature, api_key=self.openai_api_key
52
+ )
53
+ self.chain = self._create_chain()
54
+
55
+ def _get_system_prompt(self) -> ChatPromptTemplate:
56
+
57
+ return ChatPromptTemplate.from_messages(
58
+ [
59
+ (
60
+ "system",
61
+ f"""You will generate a short image description (one paragraph max)
62
+ which will be later used for generating an image taking into
63
+ account that this images will be used for evaluating the
64
+ user how well can describe this image in the context of
65
+ an {self.level} Speaking English exam.
66
+
67
+ {self.description}
68
+
69
+ Topics about image descriptions which can appear:
70
+ {self.exam_prompt}
71
+ """,
72
+ ),
73
+ ("human", "{base_input}"),
74
+ ]
75
+ )
76
+
77
+ def _create_chain(self) -> Runnable[Any, Any]:
78
+
79
+ img_prompt = PromptTemplate(
80
+ input_variables=["image_desc"],
81
+ template="""You will now act as a prompt generator. I will describe an image to you, and you will create a prompt
82
+ that could be used for image-generation. The style must be realistic:
83
+ Description: {image_desc}""",
84
+ )
85
+
86
+ return (
87
+ {"image_desc": self._get_system_prompt() | self.chat_llm | StrOutputParser()}
88
+ | img_prompt
89
+ | self.img_prompt_model
90
+ | StrOutputParser()
91
+ )
92
+
93
+ def generate(self) -> str:
94
+ """
95
+ Generate function to create and return an image URL based on input parameters.
96
+ """
97
+ img_url = self.dalle.run(self.chain.invoke({"base_input": "Generate image description"})[:999])
98
+ return img_url
src/models/{generator.py → gen/text_generator.py} RENAMED
@@ -3,18 +3,16 @@ from typing import Any, List, Type
3
 
4
  from langchain.memory import ChatMessageHistory, ConversationBufferWindowMemory
5
  from langchain.output_parsers import PydanticOutputParser
6
- from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder, PromptTemplate
7
- from langchain.schema import AIMessage, HumanMessage
8
- from langchain_community.utilities.dalle_image_generator import DallEAPIWrapper
9
  from langchain_core.output_parsers import StrOutputParser
10
  from langchain_core.pydantic_v1 import BaseModel, Field, SecretStr
11
  from langchain_core.runnables import Runnable, RunnableLambda, RunnablePassthrough
12
- from langchain_openai import OpenAI
13
-
14
- from src.models.lc_base_model import ContentGenerator
15
 
16
 
17
  class QuestionGenerator(ContentGenerator):
 
18
  class Question(BaseModel):
19
  question: str = Field(alias="Question", description="A question based on the given guidelines")
20
 
@@ -23,9 +21,11 @@ class QuestionGenerator(ContentGenerator):
23
  exam_prompt: str,
24
  level: str,
25
  description: str,
26
- history_chat: List[HumanMessage | AIMessage],
27
  openai_api_key: SecretStr,
28
  chat_temperature: float = 0.3,
 
 
29
  ) -> None:
30
  """
31
  Initializes the object with the given exam prompt, level, description, history chat, and OpenAI API key.
@@ -36,16 +36,18 @@ class QuestionGenerator(ContentGenerator):
36
  description (str): The description of the exam.
37
  history_chat (List[HumanMessage | AIMessage]): List of chat messages from history.
38
  openai_api_key (SecretStr): The API key for OpenAI.
 
 
39
 
40
  Returns:
41
  None
42
  """
43
- super().__init__(openai_api_key=openai_api_key, chat_temperature=chat_temperature)
44
  self.level = level
45
  self.exam_prompt = exam_prompt
46
  self.description = description
47
  self.memory = ConversationBufferWindowMemory(
48
- chat_memory=ChatMessageHistory(messages=history_chat), return_messages=True, k=20
49
  )
50
  self.chain = self._create_chain()
51
 
@@ -126,80 +128,3 @@ class QuestionGenerator(ContentGenerator):
126
  self.memory.chat_memory.add_ai_message(response)
127
 
128
  return response
129
-
130
-
131
- class ImgGenerator(ContentGenerator):
132
-
133
- def __init__(
134
- self,
135
- exam_prompt: str,
136
- level: str,
137
- description: str,
138
- openai_api_key: SecretStr,
139
- chat_temperature: float = 0.3,
140
- img_size: str = "256x256",
141
- ) -> None:
142
- """
143
- Initializes the class with the exam prompt, level, description, OpenAI API key, and optional image size.
144
-
145
- Parameters:
146
- exam_prompt (str): The prompt for the exam.
147
- level (str): The level of the exam.
148
- description (str): Description of the exam.
149
- openai_api_key (SecretStr): The OpenAI API key.
150
- img_size (str, optional): The size of the image. Default is "256x256".
151
-
152
- Returns:
153
- None
154
- """
155
- super().__init__(openai_api_key, chat_temperature)
156
- self.level = level
157
- self.exam_prompt = exam_prompt
158
- self.description = description
159
- self.dalle = DallEAPIWrapper(size=img_size, api_key=self.openai_api_key.get_secret_value()) # type: ignore[call-arg]
160
- self.chain = self._create_chain()
161
-
162
- def _get_system_prompt(self) -> ChatPromptTemplate:
163
-
164
- return ChatPromptTemplate.from_messages(
165
- [
166
- (
167
- "system",
168
- f"""You will generate a short image description (one paragraph max)
169
- which will be later used for generating an image taking into
170
- account that this images will be used for evaluating the
171
- user how well can describe this image in the context of
172
- an {self.level} Speaking English exam.
173
-
174
- {self.description}
175
-
176
- Topics about image descriptions which can appear:
177
- {self.exam_prompt}
178
- """,
179
- ),
180
- ("human", "{base_input}"),
181
- ]
182
- )
183
-
184
- def _create_chain(self) -> Runnable[Any, Any]:
185
-
186
- img_prompt = PromptTemplate(
187
- input_variables=["image_desc"],
188
- template="""You will now act as a prompt generator. I will describe an image to you, and you will create a prompt
189
- that could be used for image-generation. The style must be realistic:
190
- Description: {image_desc}""",
191
- )
192
-
193
- return (
194
- {"image_desc": self._get_system_prompt() | self.chat_llm | StrOutputParser()}
195
- | img_prompt
196
- | OpenAI(temperature=0.7, api_key=self.openai_api_key)
197
- | StrOutputParser()
198
- )
199
-
200
- def generate(self) -> str:
201
- """
202
- Generate function to create and return an image URL based on input parameters.
203
- """
204
- img_url = self.dalle.run(self.chain.invoke({"base_input": "Generate image description"})[:999])
205
- return img_url
 
3
 
4
  from langchain.memory import ChatMessageHistory, ConversationBufferWindowMemory
5
  from langchain.output_parsers import PydanticOutputParser
6
+ from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
7
+ from langchain.schema import BaseMessage
 
8
  from langchain_core.output_parsers import StrOutputParser
9
  from langchain_core.pydantic_v1 import BaseModel, Field, SecretStr
10
  from langchain_core.runnables import Runnable, RunnableLambda, RunnablePassthrough
11
+ from src.models.base.base_model import ContentGenerator
 
 
12
 
13
 
14
  class QuestionGenerator(ContentGenerator):
15
+
16
  class Question(BaseModel):
17
  question: str = Field(alias="Question", description="A question based on the given guidelines")
18
 
 
21
  exam_prompt: str,
22
  level: str,
23
  description: str,
24
+ history_chat: List[BaseMessage],
25
  openai_api_key: SecretStr,
26
  chat_temperature: float = 0.3,
27
+ n_messages_memory: int = 20,
28
+ chat_model: str = "gpt-3.5-turbo",
29
  ) -> None:
30
  """
31
  Initializes the object with the given exam prompt, level, description, history chat, and OpenAI API key.
 
36
  description (str): The description of the exam.
37
  history_chat (List[HumanMessage | AIMessage]): List of chat messages from history.
38
  openai_api_key (SecretStr): The API key for OpenAI.
39
+ chat_temperature (float, optional): The temperature to use for chat. Defaults to 0.3.
40
+ n_messages_memory (int, optional): The number of messages to keep in memory. Defaults to 20.
41
 
42
  Returns:
43
  None
44
  """
45
+ super().__init__(openai_api_key=openai_api_key, chat_temperature=chat_temperature, chat_model=chat_model)
46
  self.level = level
47
  self.exam_prompt = exam_prompt
48
  self.description = description
49
  self.memory = ConversationBufferWindowMemory(
50
+ chat_memory=ChatMessageHistory(messages=history_chat), return_messages=True, k=n_messages_memory
51
  )
52
  self.chain = self._create_chain()
53
 
 
128
  self.memory.chat_memory.add_ai_message(response)
129
 
130
  return response
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/models/model_factory.py CHANGED
@@ -1,13 +1,14 @@
1
  from abc import ABC, abstractmethod
2
  from typing import Any, List, Optional
3
 
4
- from langchain.schema import AIMessage, HumanMessage
5
  from langchain_core.pydantic_v1 import SecretStr
6
 
7
- from src.models.generator import ImgGenerator, QuestionGenerator
8
- from src.models.lc_base_model import ChainGenerator, ContentGenerator, EvaluationChatModel
9
- from src.models.lc_img_desc_model import EvaluationChatModelImg
10
- from src.models.lc_qa_model import EvaluationChatModelQA
 
11
 
12
 
13
  class ModelFactory(ABC):
@@ -21,7 +22,12 @@ class ModelFactory(ABC):
21
 
22
  class EvaluationChatModelFactory(ModelFactory):
23
 
24
- def create_model(self, model_class: str, openai_api_key: SecretStr, **kwargs: Any) -> EvaluationChatModel:
 
 
 
 
 
25
  """
26
  Create a model based on the provided model class and OpenAI API key.
27
 
@@ -38,9 +44,15 @@ class EvaluationChatModelFactory(ModelFactory):
38
  """
39
  match model_class:
40
  case "qa":
41
- return EvaluationChatModelQA(openai_api_key=openai_api_key, **kwargs)
 
 
 
42
  case "img_desc":
43
- return EvaluationChatModelImg(openai_api_key=openai_api_key, **kwargs)
 
 
 
44
  case _:
45
  raise ValueError("Invalid model class provided")
46
 
@@ -51,7 +63,10 @@ class GeneratorModelFactory(ModelFactory):
51
  self,
52
  model_class: str,
53
  openai_api_key: SecretStr,
54
- history_chat: Optional[List[HumanMessage | AIMessage]] = None,
 
 
 
55
  img_size: str = "256x256",
56
  **kwargs: Any,
57
  ) -> ContentGenerator:
@@ -62,6 +77,9 @@ class GeneratorModelFactory(ModelFactory):
62
  model_class (str): The class of the model to create.
63
  openai_api_key (SecretStr): The API key for OpenAI.
64
  history_chat (Optional[list], optional): List of chat history. Defaults to None.
 
 
 
65
  img_size (str, optional): The size of the image. Defaults to "256x256".
66
  **kwargs (Any): Additional keyword arguments.
67
 
@@ -70,8 +88,19 @@ class GeneratorModelFactory(ModelFactory):
70
  """
71
  match model_class:
72
  case "qa":
73
- return QuestionGenerator(openai_api_key=openai_api_key, history_chat=history_chat or [], **kwargs)
 
 
 
 
 
74
  case "img_desc":
75
- return ImgGenerator(openai_api_key=openai_api_key, img_size=img_size, **kwargs)
 
 
 
 
 
 
76
  case _:
77
  raise ValueError("Invalid model class provided")
 
1
  from abc import ABC, abstractmethod
2
  from typing import Any, List, Optional
3
 
4
+ from langchain.schema import BaseMessage
5
  from langchain_core.pydantic_v1 import SecretStr
6
 
7
+ from src.models.base.base_model import ChainGenerator, ContentGenerator, EvaluationChatModel
8
+ from src.models.evaluator.img_evaluator import EvaluationChatModelImg
9
+ from src.models.evaluator.text_evaluator import EvaluationChatModelQA
10
+ from src.models.gen.img_generator import ImgGenerator
11
+ from src.models.gen.text_generator import QuestionGenerator
12
 
13
 
14
  class ModelFactory(ABC):
 
22
 
23
  class EvaluationChatModelFactory(ModelFactory):
24
 
25
+ def create_model(
26
+ self,
27
+ model_class: str,
28
+ openai_api_key: SecretStr,
29
+ **kwargs: Any,
30
+ ) -> EvaluationChatModel:
31
  """
32
  Create a model based on the provided model class and OpenAI API key.
33
 
 
44
  """
45
  match model_class:
46
  case "qa":
47
+ return EvaluationChatModelQA(
48
+ openai_api_key=openai_api_key,
49
+ **kwargs,
50
+ )
51
  case "img_desc":
52
+ return EvaluationChatModelImg(
53
+ openai_api_key=openai_api_key,
54
+ **kwargs,
55
+ )
56
  case _:
57
  raise ValueError("Invalid model class provided")
58
 
 
63
  self,
64
  model_class: str,
65
  openai_api_key: SecretStr,
66
+ history_chat: Optional[List[BaseMessage]] = None,
67
+ n_messages_memory: int = 20,
68
+ prompt_model: str = "gpt-3.5-turbo",
69
+ prompt_model_temperature: float = 0.3,
70
  img_size: str = "256x256",
71
  **kwargs: Any,
72
  ) -> ContentGenerator:
 
77
  model_class (str): The class of the model to create.
78
  openai_api_key (SecretStr): The API key for OpenAI.
79
  history_chat (Optional[list], optional): List of chat history. Defaults to None.
80
+ n_messages_memory (int, optional): Number of messages to keep in memory. Defaults to 20.
81
+ prompt_model (str, optional): The prompt model. Defaults to "gpt-3.5-turbo".
82
+ prompt_model_temperature (float, optional): The prompt model temperature. Defaults to 0.3.
83
  img_size (str, optional): The size of the image. Defaults to "256x256".
84
  **kwargs (Any): Additional keyword arguments.
85
 
 
88
  """
89
  match model_class:
90
  case "qa":
91
+ return QuestionGenerator(
92
+ openai_api_key=openai_api_key,
93
+ history_chat=history_chat or [],
94
+ n_messages_memory=n_messages_memory,
95
+ **kwargs,
96
+ )
97
  case "img_desc":
98
+ return ImgGenerator(
99
+ openai_api_key=openai_api_key,
100
+ prompt_model=prompt_model,
101
+ prompt_model_temperature=prompt_model_temperature,
102
+ img_size=img_size,
103
+ **kwargs,
104
+ )
105
  case _:
106
  raise ValueError("Invalid model class provided")