Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
ayushi0430
commited on
Commit
•
64e3457
1
Parent(s):
d409109
shopping pipeline
Browse files- .gitignore +1 -0
- Dockerfile +12 -2
- generation.py +158 -0
- run-adhoc.sh +12 -1
- run-pipeline.sh +15 -0
- start.sh +10 -1
.gitignore
CHANGED
@@ -11,3 +11,4 @@ eval-results/
|
|
11 |
eval-queue-bk/
|
12 |
eval-results-bk/
|
13 |
logs/
|
|
|
|
11 |
eval-queue-bk/
|
12 |
eval-results-bk/
|
13 |
logs/
|
14 |
+
output-data/
|
Dockerfile
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
FROM python:3.
|
2 |
|
3 |
WORKDIR /code
|
4 |
|
@@ -6,7 +6,17 @@ COPY ./requirements.txt /code/requirements.txt
|
|
6 |
|
7 |
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
|
8 |
|
9 |
-
COPY
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
|
11 |
|
12 |
EXPOSE 7860
|
|
|
1 |
+
FROM python:3.10
|
2 |
|
3 |
WORKDIR /code
|
4 |
|
|
|
6 |
|
7 |
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
|
8 |
|
9 |
+
COPY scripts /code/scripts
|
10 |
+
COPY src /code/src
|
11 |
+
|
12 |
+
COPY app.py /code/app.py
|
13 |
+
COPY main_backend.py /code/main_backend.py
|
14 |
+
|
15 |
+
# to generate adhoc result files --> to be deleted once generation pipeline is stable
|
16 |
+
COPY adhoc.py /code/adhoc.py
|
17 |
+
|
18 |
+
# answer and score generation pipeline
|
19 |
+
COPY generation.py /code/generation.py
|
20 |
|
21 |
|
22 |
EXPOSE 7860
|
generation.py
ADDED
@@ -0,0 +1,158 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from lamini.generation.generation_node import GenerationNode
|
2 |
+
from lamini.generation.generation_pipeline import GenerationPipeline
|
3 |
+
from lamini.generation.base_prompt_object import PromptObject
|
4 |
+
from typing import Union, Iterator, AsyncIterator
|
5 |
+
from src.backend.lamini_eval.datasets.ecommerce.shopping_dataset import load_shopping_dataset
|
6 |
+
from src.envs import DATASET_PATH, LAMINI_API_KEY
|
7 |
+
import logging
|
8 |
+
import asyncio
|
9 |
+
import lamini
|
10 |
+
import jsonlines
|
11 |
+
from tqdm import tqdm
|
12 |
+
|
13 |
+
|
14 |
+
lamini.api_key = LAMINI_API_KEY
|
15 |
+
|
16 |
+
logger = logging.getLogger(__name__)
|
17 |
+
|
18 |
+
logging.basicConfig(
|
19 |
+
level=logging.DEBUG,
|
20 |
+
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
21 |
+
)
|
22 |
+
|
23 |
+
|
24 |
+
class AnswerScorePipeline(GenerationPipeline):
|
25 |
+
def __init__(self):
|
26 |
+
super(AnswerScorePipeline, self).__init__()
|
27 |
+
|
28 |
+
self.answer_generator = AnswerGenerator()
|
29 |
+
self.score_generator = ScoreGenerator()
|
30 |
+
|
31 |
+
def forward(self, x):
|
32 |
+
ans = self.answer_generator(x)
|
33 |
+
score = self.score_generator(ans)
|
34 |
+
return score
|
35 |
+
|
36 |
+
|
37 |
+
class AnswerGenerator(GenerationNode):
|
38 |
+
def __init__(self):
|
39 |
+
super(AnswerGenerator, self).__init__(
|
40 |
+
model_name="mistralai/Mistral-7B-Instruct-v0.1", max_tokens=200
|
41 |
+
)
|
42 |
+
|
43 |
+
def generate(
|
44 |
+
self,
|
45 |
+
prompt: Union[Iterator[PromptObject], AsyncIterator[PromptObject]],
|
46 |
+
*args,
|
47 |
+
**kwargs,
|
48 |
+
):
|
49 |
+
prompts = self.transform_prompt(prompt)
|
50 |
+
op_type = {
|
51 |
+
"product_name": "str",
|
52 |
+
"product_description": "str",
|
53 |
+
"product_id": "str"
|
54 |
+
}
|
55 |
+
results = super(AnswerGenerator, self).generate(prompts, output_type=op_type, *args, **kwargs)
|
56 |
+
processed_results = self.process_results(results)
|
57 |
+
return processed_results
|
58 |
+
|
59 |
+
async def process_results(self, results):
|
60 |
+
async for result in results:
|
61 |
+
logger.info(f"Generated answer for {result}")
|
62 |
+
if result is None:
|
63 |
+
continue
|
64 |
+
yield result
|
65 |
+
|
66 |
+
async def transform_prompt(self, prompts):
|
67 |
+
async for prompt in prompts:
|
68 |
+
prompt.prompt = self.make_prompt(prompt)
|
69 |
+
yield prompt
|
70 |
+
|
71 |
+
def make_prompt(self, chunk):
|
72 |
+
prompt = (
|
73 |
+
"You are an expert shopper at Instacart."
|
74 |
+
)
|
75 |
+
prompt += "You are helping a customer find a product. "
|
76 |
+
prompt += "Include the product name, id, and detailed description in your answer. "
|
77 |
+
prompt += "A product id is a number between 0 and 100,000. "
|
78 |
+
prompt += "The customer asks\n"
|
79 |
+
prompt += chunk.data["question"]
|
80 |
+
print("prompt:", prompt)
|
81 |
+
return prompt
|
82 |
+
|
83 |
+
|
84 |
+
class ScoreGenerator(GenerationNode):
|
85 |
+
def __init__(self):
|
86 |
+
super(ScoreGenerator, self).__init__(
|
87 |
+
model_name="mistralai/Mistral-7B-Instruct-v0.1", max_tokens=200
|
88 |
+
)
|
89 |
+
|
90 |
+
def generate(
|
91 |
+
self,
|
92 |
+
prompt: Union[Iterator[PromptObject], AsyncIterator[PromptObject]],
|
93 |
+
*args,
|
94 |
+
**kwargs,
|
95 |
+
):
|
96 |
+
prompts = self.transform_prompt(prompt)
|
97 |
+
results = super(ScoreGenerator, self).generate(prompts, *args, **kwargs)
|
98 |
+
processed_results = self.process_results(results)
|
99 |
+
return processed_results
|
100 |
+
|
101 |
+
async def process_results(self, results):
|
102 |
+
async for result in results:
|
103 |
+
logger.info(f"Generated score for {result}")
|
104 |
+
if result is None:
|
105 |
+
continue
|
106 |
+
yield result
|
107 |
+
|
108 |
+
async def transform_prompt(self, prompts):
|
109 |
+
async for prompt in prompts:
|
110 |
+
prompt.data["question"] = prompt.prompt
|
111 |
+
prompt.prompt = self.make_prompt(prompt)
|
112 |
+
yield prompt
|
113 |
+
|
114 |
+
def make_prompt(self, chunk):
|
115 |
+
prompt = (
|
116 |
+
"A model is going to answer a question. Your job is to score the answer, comparing it to a golden reference. You are an expert scorer.\n\n"
|
117 |
+
)
|
118 |
+
prompt += f"Rate the answer using a score from 1 (lowest match) to 5 (highest match).\n"
|
119 |
+
prompt += chunk.data["rubric"]
|
120 |
+
prompt += "Use the full range. Read the gold answer carefully. "
|
121 |
+
prompt += "Explain your score in 2-3 short sentences not exceeding 100 words each, then assign a score. "
|
122 |
+
prompt += "Output your score as a JSON object in the format {\"explanation\" : str, \"score\" : int}\n"
|
123 |
+
prompt += "Use single quotes within your explanation. End your explanation with a double quote.\n"
|
124 |
+
prompt += "Prefer answers that are most similar to the gold answer, even if the gold answer refused to answer the question.\n\n"
|
125 |
+
prompt += f"========== question =========\n{chunk.data['question']}\n\n"
|
126 |
+
prompt += f"========== gold answer =========\n{chunk.data['expected_response']}\n\n"
|
127 |
+
prompt += f"========== model answer =========\n{chunk.data['response']}\n\n"
|
128 |
+
prompt += "=" * 40 + "\n\n"
|
129 |
+
prompt += f"How would you score the model's answer compared to the gold answer (using the 1-5 scale defined above)?\n\n"
|
130 |
+
print("prompt:", prompt)
|
131 |
+
return prompt
|
132 |
+
|
133 |
+
|
134 |
+
async def main():
|
135 |
+
dataset = load_shopping_dataset(DATASET_PATH)
|
136 |
+
|
137 |
+
answers = AnswerScorePipeline().call(dataset)
|
138 |
+
await print_answers(answers)
|
139 |
+
|
140 |
+
|
141 |
+
async def print_answers(answers):
|
142 |
+
path = "/code/data/model-answers.jsonl"
|
143 |
+
|
144 |
+
with jsonlines.open(path, "w") as writer:
|
145 |
+
pbar = tqdm(desc="Saving answers", unit=" answers")
|
146 |
+
async for answer in answers:
|
147 |
+
answer = {
|
148 |
+
"prompt": answer.prompt,
|
149 |
+
"question": answer.data["question"],
|
150 |
+
"answer": answer.response,
|
151 |
+
}
|
152 |
+
print(f"\n\n=======\n{answer}\n\n")
|
153 |
+
writer.write(answer)
|
154 |
+
pbar.update()
|
155 |
+
|
156 |
+
|
157 |
+
if __name__ == "__main__":
|
158 |
+
asyncio.run(main())
|
run-adhoc.sh
CHANGED
@@ -1,2 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
docker buildx build --platform=linux/amd64 -t adhoc .
|
2 |
-
docker run -it --rm --platform=linux/amd64
|
|
|
1 |
+
#!/bin/bash
|
2 |
+
|
3 |
+
# Safely execute this bash script
|
4 |
+
# e exit on first failure
|
5 |
+
# x all executed commands are printed to the terminal
|
6 |
+
# u unset variables are errors
|
7 |
+
# a export all variables to the environment
|
8 |
+
# E any trap on ERR is inherited by shell functions
|
9 |
+
# -o pipefail | produces a failure code if any stage fails
|
10 |
+
set -Eeuoxa pipefail
|
11 |
+
|
12 |
docker buildx build --platform=linux/amd64 -t adhoc .
|
13 |
+
docker run -it --rm --platform=linux/amd64 adhoc python adhoc.py
|
run-pipeline.sh
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/bin/bash
|
2 |
+
|
3 |
+
# Safely execute this bash script
|
4 |
+
# e exit on first failure
|
5 |
+
# x all executed commands are printed to the terminal
|
6 |
+
# u unset variables are errors
|
7 |
+
# a export all variables to the environment
|
8 |
+
# E any trap on ERR is inherited by shell functions
|
9 |
+
# -o pipefail | produces a failure code if any stage fails
|
10 |
+
set -Eeuoxa pipefail
|
11 |
+
|
12 |
+
LOCAL_DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
13 |
+
|
14 |
+
docker buildx build --platform=linux/amd64 -t pipeline .
|
15 |
+
docker run -it --rm --platform=linux/amd64 -v $LOCAL_DIRECTORY/output-data:/code/data pipeline python3 generation.py
|
start.sh
CHANGED
@@ -1,5 +1,14 @@
|
|
1 |
#!/bin/bash
|
2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
for ARGUMENT in "$@"
|
4 |
do
|
5 |
KEY=$(echo $ARGUMENT | cut -f1 -d=)
|
@@ -15,4 +24,4 @@ echo "Run mode is: $RUN_MODE"
|
|
15 |
echo "Model passed is: $LOCAL_MODEL_NAME"
|
16 |
|
17 |
docker buildx build --platform=linux/amd64 -t ldr .
|
18 |
-
docker run -it --rm -p 7860:7860 --platform=linux/amd64 -e
|
|
|
1 |
#!/bin/bash
|
2 |
|
3 |
+
# Safely execute this bash script
|
4 |
+
# e exit on first failure
|
5 |
+
# x all executed commands are printed to the terminal
|
6 |
+
# u unset variables are errors
|
7 |
+
# a export all variables to the environment
|
8 |
+
# E any trap on ERR is inherited by shell functions
|
9 |
+
# -o pipefail | produces a failure code if any stage fails
|
10 |
+
set -Eeuoxa pipefail
|
11 |
+
|
12 |
for ARGUMENT in "$@"
|
13 |
do
|
14 |
KEY=$(echo $ARGUMENT | cut -f1 -d=)
|
|
|
24 |
echo "Model passed is: $LOCAL_MODEL_NAME"
|
25 |
|
26 |
docker buildx build --platform=linux/amd64 -t ldr .
|
27 |
+
docker run -it --rm -p 7860:7860 --platform=linux/amd64 -e RUN_MODE=$RUN_MODE -e LOCAL_MODEL_NAME=$LOCAL_MODEL_NAME ldr python app.py
|