Spaces:
Sleeping
Sleeping
Commit
·
c39d1b7
1
Parent(s):
de14bd5
feat: parameterized models
Browse files- CHANGELOG.md +4 -0
- README.md +15 -1
- poetry.lock +0 -0
- pyproject.toml +1 -1
- src/config.json +14 -1
- src/main.py +9 -0
- src/models/{lc_base_model.py → base/base_model.py} +26 -4
- src/models/{lc_img_desc_model.py → evaluator/img_evaluator.py} +28 -7
- src/models/{lc_qa_model.py → evaluator/text_evaluator.py} +13 -4
- src/models/gen/img_generator.py +98 -0
- src/models/{generator.py → gen/text_generator.py} +11 -86
- src/models/model_factory.py +40 -11
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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.
|
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 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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__(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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=
|
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__(
|
33 |
-
self
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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.
|
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 |
-
|
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":
|
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__(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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=
|
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
|
7 |
-
from langchain.schema import
|
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
|
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[
|
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=
|
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
|
5 |
from langchain_core.pydantic_v1 import SecretStr
|
6 |
|
7 |
-
from src.models.
|
8 |
-
from src.models.
|
9 |
-
from src.models.
|
10 |
-
from src.models.
|
|
|
11 |
|
12 |
|
13 |
class ModelFactory(ABC):
|
@@ -21,7 +22,12 @@ class ModelFactory(ABC):
|
|
21 |
|
22 |
class EvaluationChatModelFactory(ModelFactory):
|
23 |
|
24 |
-
def create_model(
|
|
|
|
|
|
|
|
|
|
|
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(
|
|
|
|
|
|
|
42 |
case "img_desc":
|
43 |
-
return EvaluationChatModelImg(
|
|
|
|
|
|
|
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[
|
|
|
|
|
|
|
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(
|
|
|
|
|
|
|
|
|
|
|
74 |
case "img_desc":
|
75 |
-
return ImgGenerator(
|
|
|
|
|
|
|
|
|
|
|
|
|
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")
|