luisrodriguesphd commited on
Commit
9c79212
1 Parent(s): 1ab7f5d

feat: update llm provider to groq and model to llama 3 8b

Browse files
Dockerfile CHANGED
@@ -21,6 +21,9 @@ ENV MPLCONFIGDIR=$MPLCONFIGDIR
21
  ARG ENTRYPOINT_PATH="./entrypoint.sh"
22
  ENV ENTRYPOINT_PATH=$ENTRYPOINT_PATH
23
 
 
 
 
24
  # Create the /code/ directory a ser permissions rwe
25
  RUN mkdir -p /code/&& \
26
  chmod -R 777 /code/
@@ -55,7 +58,6 @@ COPY . .
55
  RUN pip install -e . && \
56
  python src/resume_worth/pipelines/data_indexing/pipeline.py
57
 
58
- RUN python src/resume_worth/pipelines/text_generation/pipeline.py && \
59
- chmod +x $ENTRYPOINT_PATH
60
 
61
  ENTRYPOINT $ENTRYPOINT_PATH
 
21
  ARG ENTRYPOINT_PATH="./entrypoint.sh"
22
  ENV ENTRYPOINT_PATH=$ENTRYPOINT_PATH
23
 
24
+ # RUN --mount=type=secret,id=GROQ_API_KEY,mode=0444,required=true \
25
+ # echo "GROQ_API_KEY=$(cat /run/secrets/GROQ_API_KEY)"
26
+
27
  # Create the /code/ directory a ser permissions rwe
28
  RUN mkdir -p /code/&& \
29
  chmod -R 777 /code/
 
58
  RUN pip install -e . && \
59
  python src/resume_worth/pipelines/data_indexing/pipeline.py
60
 
61
+ RUN chmod +x $ENTRYPOINT_PATH
 
62
 
63
  ENTRYPOINT $ENTRYPOINT_PATH
conf/.env.example CHANGED
@@ -1,3 +1,6 @@
 
 
 
1
  # OpenAI (to text generation)
2
  OPENAI_API_KEY=""
3
  OPENAI_ORG_ID=""
 
1
+ # Groq Cloud (to text generation)
2
+ GROQ_API_KEY="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"
3
+
4
  # OpenAI (to text generation)
5
  OPENAI_API_KEY=""
6
  OPENAI_ORG_ID=""
conf/params.yml CHANGED
@@ -1,3 +1,8 @@
 
 
 
 
 
1
  # Data
2
  ingestion_data_dir: ["data", "02_processed"]
3
  ingestion_metadata_dir: ["data", "02_processed", "metadata"]
@@ -16,16 +21,15 @@ embedding_dir: ["data", "03_indexed"]
16
 
17
 
18
  # LLM / Text Generation
 
19
  # See instructions for parameters: https://www.ibm.com/docs/en/watsonx-as-a-service?topic=lab-model-parameters-prompting
20
  generative_model:
21
- model_name: "M4-ai/tau-1.8B"
 
22
  model_kwargs:
23
- trust_remote_code: True
24
- generate_kwargs:
25
- top_k: 30
26
  top_p: 0.7
 
27
  temperature: 0.3
28
- max_new_tokens: 256
29
  # See instructions for the prompt: https://huggingface.co/spaces/Locutusque/Locutusque-Models/blob/main/app.py
30
  prompt_dir: ["data", "04_prompts"]
31
  promp_file: "prompt_template_for_explaning_why_is_a_good_fit.json"
 
1
+ # Conf
2
+ conf_dir: ["conf"]
3
+ secrets_file: ".env"
4
+
5
+
6
  # Data
7
  ingestion_data_dir: ["data", "02_processed"]
8
  ingestion_metadata_dir: ["data", "02_processed", "metadata"]
 
21
 
22
 
23
  # LLM / Text Generation
24
+ # Suggestion: huggingface|M4-ai/tau-1.8B; groq|llama3-8b-8192
25
  # See instructions for parameters: https://www.ibm.com/docs/en/watsonx-as-a-service?topic=lab-model-parameters-prompting
26
  generative_model:
27
+ model_provider: "groq"
28
+ model_name: "llama3-8b-8192"
29
  model_kwargs:
 
 
 
30
  top_p: 0.7
31
+ generate_kwargs:
32
  temperature: 0.3
 
33
  # See instructions for the prompt: https://huggingface.co/spaces/Locutusque/Locutusque-Models/blob/main/app.py
34
  prompt_dir: ["data", "04_prompts"]
35
  promp_file: "prompt_template_for_explaning_why_is_a_good_fit.json"
requirements.in CHANGED
@@ -7,6 +7,7 @@ pandas
7
  # to build LLM Apps
8
  langchain
9
  langchain-community
 
10
  sentence-transformers>=2.3.1
11
  chromadb
12
 
 
7
  # to build LLM Apps
8
  langchain
9
  langchain-community
10
+ langchain_groq
11
  sentence-transformers>=2.3.1
12
  chromadb
13
 
src/resume_worth/pipelines/text_generation/nodes.py CHANGED
@@ -1,8 +1,11 @@
1
  import os
2
  os.environ['HF_HOME'] = ".cache/huggingface"
3
 
 
 
4
  from langchain_community.llms.huggingface_pipeline import HuggingFacePipeline
5
  from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
 
6
  from langchain_core.prompts import PromptTemplate
7
  from langchain.prompts import load_prompt
8
  from functools import lru_cache
@@ -13,26 +16,71 @@ transformers.logging.set_verbosity_error()
13
 
14
 
15
  #@lru_cache(maxsize=None)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  def load_hf_text_generation_model_to_langchain(
17
- model_name:str='gpt2',
18
- model_kwargs:dict={
19
- 'trust_remote_code': True,
20
- },
21
- generate_kwargs:dict={
22
- 'top_k': 50,
23
- 'top_p': 0.95,
24
- 'temperature': 0.4,
25
- 'max_new_tokens': 1024,
26
- }
27
  ):
28
  """
29
- Function to load a text generation model hosted on Hugging Face to se used in LangChain.
30
  More info, see: https://python.langchain.com/docs/integrations/llms/huggingface_pipelines/
31
  """
32
 
33
- print(f"-> Load a pretrained text embedding model {model_name}")
34
-
35
- # https://huggingface.co/apple/OpenELM
36
  tokenizer = AutoTokenizer.from_pretrained(model_name, **model_kwargs)
37
  model = AutoModelForCausalLM.from_pretrained(model_name, **model_kwargs)
38
 
@@ -68,10 +116,10 @@ def load_langchain_prompt_template(promp_path: str):
68
  return prompt
69
 
70
 
71
- def create_langchain_chain(prompt: PromptTemplate, hf_text_generation: HuggingFacePipeline):
72
  """
73
- Create a chain by composing the HF text generation model with a LangChain prompt template.
74
  More info, see: https://python.langchain.com/docs/integrations/llms/huggingface_pipelines/
75
  """
76
- chain = prompt | hf_text_generation
77
  return chain
 
1
  import os
2
  os.environ['HF_HOME'] = ".cache/huggingface"
3
 
4
+ from typing import Union
5
+ from resume_worth.utils.utils import set_secrets
6
  from langchain_community.llms.huggingface_pipeline import HuggingFacePipeline
7
  from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
8
+ from langchain_groq import ChatGroq
9
  from langchain_core.prompts import PromptTemplate
10
  from langchain.prompts import load_prompt
11
  from functools import lru_cache
 
16
 
17
 
18
  #@lru_cache(maxsize=None)
19
+ def load_text_generation_model(
20
+ model_provider:str='groq',
21
+ model_name:str='llama3-8b-8192',
22
+ model_kwargs:dict={},
23
+ generate_kwargs:dict={
24
+ 'temperature': 0.4,
25
+ },
26
+ ):
27
+ """Function to load a text generation model according to the provider."""
28
+
29
+ print(f"-> Load {model_name} text generation model from {model_provider}")
30
+
31
+ if model_provider=="huggingface":
32
+ return load_hf_text_generation_model_to_langchain(model_name, model_kwargs, generate_kwargs)
33
+
34
+ elif model_provider=="groq":
35
+ set_secrets()
36
+ return load_groq_text_generation_model_to_langchain(model_name, model_kwargs, generate_kwargs)
37
+
38
+ else:
39
+ raise Exception("Sorry, the code has no support for this provider yet.")
40
+
41
+
42
+ def load_groq_text_generation_model_to_langchain(
43
+ model_name:str='llama3-8b-8192',
44
+ model_kwargs:dict={
45
+ 'top_k': 50,
46
+ 'top_p': 0.95,
47
+ 'max_new_tokens': 1024,
48
+ },
49
+ generate_kwargs:dict={
50
+ 'temperature': 0.4,
51
+ }
52
+ ):
53
+ """
54
+ Function to load a text generation model hosted on Groq to be used in LangChain.
55
+ More info, see: https://console.groq.com/docs/quickstart
56
+ """
57
+
58
+ groq_api_key = os.environ.get('GROQ_API_KEY', None)
59
+ if groq_api_key is None:
60
+ raise ValueError("GROQ_API_KEY is not set.")
61
+
62
+ groq = ChatGroq(model_name=model_name, model_kwargs=model_kwargs, **generate_kwargs, groq_api_key=groq_api_key)
63
+
64
+ return groq
65
+
66
+
67
  def load_hf_text_generation_model_to_langchain(
68
+ model_name:str='gpt2',
69
+ model_kwargs:dict={
70
+ 'trust_remote_code': True,
71
+ },
72
+ generate_kwargs:dict={
73
+ 'top_k': 50,
74
+ 'top_p': 0.95,
75
+ 'temperature': 0.4,
76
+ 'max_new_tokens': 1024,
77
+ }
78
  ):
79
  """
80
+ Function to load a text generation model hosted on Hugging Face to be used in LangChain.
81
  More info, see: https://python.langchain.com/docs/integrations/llms/huggingface_pipelines/
82
  """
83
 
 
 
 
84
  tokenizer = AutoTokenizer.from_pretrained(model_name, **model_kwargs)
85
  model = AutoModelForCausalLM.from_pretrained(model_name, **model_kwargs)
86
 
 
116
  return prompt
117
 
118
 
119
+ def create_langchain_chain(prompt: PromptTemplate, text_generation_model: Union[HuggingFacePipeline, ChatGroq]):
120
  """
121
+ Create a chain by composing the text generation model with a LangChain prompt template.
122
  More info, see: https://python.langchain.com/docs/integrations/llms/huggingface_pipelines/
123
  """
124
+ chain = prompt | text_generation_model
125
  return chain
src/resume_worth/pipelines/text_generation/pipeline.py CHANGED
@@ -7,7 +7,7 @@ This pipeline utilizes an LLM to explain why the retrieved job vacancy is a good
7
 
8
  import os
9
  from resume_worth.utils.utils import get_params
10
- from resume_worth.pipelines.text_generation.nodes import load_hf_text_generation_model_to_langchain, load_langchain_prompt_template, create_langchain_chain
11
 
12
 
13
  params = get_params()
@@ -20,7 +20,7 @@ def generate_explanation_why_resume_for_a_job(resume: str, job: str):
20
 
21
  # Stage 1 - [cacheable] Load text generation model
22
 
23
- text_generation_model = load_hf_text_generation_model_to_langchain(generative_model['model_name'], generative_model['model_kwargs'], generative_model['generate_kwargs'])
24
 
25
  # Stage 2 - [cacheable] Load text generation model
26
 
@@ -35,6 +35,9 @@ def generate_explanation_why_resume_for_a_job(resume: str, job: str):
35
 
36
  answer = text_generation_chain.invoke({"resume": resume, "job": job})
37
 
 
 
 
38
  return answer
39
 
40
 
 
7
 
8
  import os
9
  from resume_worth.utils.utils import get_params
10
+ from resume_worth.pipelines.text_generation.nodes import load_text_generation_model, load_langchain_prompt_template, create_langchain_chain
11
 
12
 
13
  params = get_params()
 
20
 
21
  # Stage 1 - [cacheable] Load text generation model
22
 
23
+ text_generation_model = load_text_generation_model(generative_model['model_provider'], generative_model['model_name'], generative_model['model_kwargs'], generative_model['generate_kwargs'])
24
 
25
  # Stage 2 - [cacheable] Load text generation model
26
 
 
35
 
36
  answer = text_generation_chain.invoke({"resume": resume, "job": job})
37
 
38
+ if generative_model['model_provider']!="huggingface":
39
+ answer = answer.content
40
+
41
  return answer
42
 
43
 
src/resume_worth/utils/utils.py CHANGED
@@ -4,6 +4,7 @@ os.environ['HF_HOME'] = ".cache/huggingface"
4
  import yaml
5
  from langchain_community.embeddings import HuggingFaceEmbeddings
6
  import fitz # imports the pymupdf library
 
7
 
8
 
9
  def get_params():
@@ -25,6 +26,22 @@ def get_params():
25
 
26
  return params
27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
 
29
  def load_embedding_model(model_name: str = "sentence-transformers/all-mpnet-base-v2", model_kwargs: dict={}, encode_kwargs: dict={}):
30
  """Load a pretrained text embedding model"""
 
4
  import yaml
5
  from langchain_community.embeddings import HuggingFaceEmbeddings
6
  import fitz # imports the pymupdf library
7
+ from functools import lru_cache
8
 
9
 
10
  def get_params():
 
26
 
27
  return params
28
 
29
+ @lru_cache(maxsize=None)
30
+ def set_secrets():
31
+ """
32
+ Function to set the secrets.
33
+ It load the parameters from .env file and set as env vars.
34
+ """
35
+ params = get_params()
36
+
37
+ secrets_path = os.path.join(params['conf_dir'], params['secrets_file'])
38
+
39
+ if os.path.exists(secrets_path):
40
+ from dotenv import load_dotenv
41
+ _ = load_dotenv(secrets_path)
42
+ else:
43
+ print(f'The secret file {secrets_path} does not exist!')
44
+
45
 
46
  def load_embedding_model(model_name: str = "sentence-transformers/all-mpnet-base-v2", model_kwargs: dict={}, encode_kwargs: dict={}):
47
  """Load a pretrained text embedding model"""