Kid Omar Costelo commited on
Commit
0276e44
·
1 Parent(s): 7e84962

Add FastAPI endpoints for scoring essays and generating prompts

Browse files
Files changed (5) hide show
  1. Dockerfile +15 -0
  2. app.py +65 -0
  3. main.py +71 -0
  4. prompt.txt +1 -0
  5. requirements.txt +4 -0
Dockerfile ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # read the doc: https://huggingface.co/docs/hub/spaces-sdks-docker
2
+ # you will also find guides on how best to write your Dockerfile
3
+
4
+ # FROM python:3.9
5
+ FROM python:latest
6
+
7
+ WORKDIR /code
8
+
9
+ COPY ./requirements.txt /code/requirements.txt
10
+
11
+ RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
12
+
13
+ COPY . .
14
+
15
+ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "7860"]
app.py ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from transformers import pipeline
2
+ from fastapi import FastAPI
3
+ from pydantic import BaseModel
4
+
5
+ # Getting the prompt from the prompt.txt file
6
+ prompt_dir = "/prompt.txt"
7
+ prompt = ''
8
+ with open(prompt_dir, 'r') as file:
9
+ prompt = file.read()
10
+
11
+
12
+ def post_process(essay):
13
+ # Find the index of the first occurrence of the word "Feedback:"
14
+ feedback_index = essay.find("Feedback:")
15
+
16
+ # If "Feedback:" is not found, return the original essay
17
+ if feedback_index == -1:
18
+ return essay
19
+
20
+ # Find the index of the newline after the first occurrence of "Feedback:"
21
+ newline_index = essay.find("\n", feedback_index)
22
+
23
+ # If newline is not found, return the original essay
24
+ if newline_index == -1:
25
+ return essay
26
+
27
+ # Return the essay up to the newline after the first occurrence of "Feedback:"
28
+ return essay[:newline_index]
29
+
30
+ def pre_process(instruction, essay):
31
+ text = f"{instruction}\n{essay}"
32
+ return text
33
+
34
+
35
+ pipe = pipeline(
36
+ "text-generation",
37
+ model = "gildead/mistral-aes-414",
38
+ device_map="auto"
39
+ )
40
+
41
+
42
+ class Message(BaseModel):
43
+ essay: str
44
+ instruction: str
45
+
46
+ app = FastAPI()
47
+
48
+
49
+ @app.get("/")
50
+ async def root():
51
+ return {"message": "Mistral API is running."}
52
+
53
+ @app.post("/score")
54
+ async def overall(message: Message):
55
+ text = pre_process(message.instruction, message.essay)
56
+ result = pipe(
57
+ f"<s>[INST] {text} [/INST]",
58
+ max_new_tokens=200,
59
+ num_return_sequences=1,)
60
+
61
+ generated_text = result[0]['generated_text']
62
+ output = generated_text.split('[/INST]', 1)[-1].strip()
63
+ final_output = post_process(output)
64
+
65
+ return {"result": final_output}
main.py ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI
2
+ from pydantic import BaseModel
3
+ from transformers import pipeline
4
+
5
+ class Message(BaseModel):
6
+ essay: str
7
+ instruction: str
8
+
9
+ # Getting the prompt from the prompt.txt file
10
+ prompt_dir = "/prompt.txt"
11
+ prompt = ''
12
+ with open(prompt_dir, 'r') as file:
13
+ prompt = file.read()
14
+
15
+
16
+ def post_process(essay):
17
+ # Find the index of the first occurrence of the word "Feedback:"
18
+ feedback_index = essay.find("Feedback:")
19
+
20
+ # If "Feedback:" is not found, return the original essay
21
+ if feedback_index == -1:
22
+ return essay
23
+
24
+ # Find the index of the newline after the first occurrence of "Feedback:"
25
+ newline_index = essay.find("\n", feedback_index)
26
+
27
+ # If newline is not found, return the original essay
28
+ if newline_index == -1:
29
+ return essay
30
+
31
+ # Return the essay up to the newline after the first occurrence of "Feedback:"
32
+ return essay[:newline_index]
33
+
34
+ def pre_process(instruction, essay):
35
+ text = f"Instruction:{instruction}\nEssay:{essay}"
36
+ return text
37
+
38
+ def generate_prompt(input):
39
+ text = f"""{prompt}\n{input}"""
40
+ return text
41
+
42
+ # Initialize your pipeline outside of your route functions
43
+ pipe = pipeline(
44
+ "text-generation",
45
+ model="gildead/mistral-aes-414",
46
+ device_map="auto"
47
+ )
48
+
49
+ # Initialize your FastAPI application
50
+ app = FastAPI()
51
+
52
+ # Define your route functions
53
+ @app.get("/")
54
+ async def root():
55
+ return {"message": "Mistral API is running."}
56
+
57
+ @app.post("/score")
58
+ async def overall(message: Message):
59
+ text = pre_process(message.instruction, message.essay)
60
+ prompt = generate_prompt(text)
61
+
62
+ result = pipe(
63
+ f"<s>[INST] {prompt} [/INST]",
64
+ max_new_tokens=200,
65
+ num_return_sequences=1,)
66
+
67
+ generated_text = result[0]['generated_text']
68
+ output = generated_text.split('[/INST]', 1)[-1].strip()
69
+ final_output = post_process(output)
70
+
71
+ return {"result": final_output}
prompt.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ I want you to act as a teacher that grades the essays of the students based on the instructions. The scores range from 1.0 to 5.0 in increments of 0.5. Your task is to give numerical score and text feedback if only needed. Text feedback must be short and one sentence only. Do not be afraid to mark perfect score. You must only reply using this format. \nScore: \nFeedback:
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ transformers
2
+ bitsandbytes
3
+ accelerate
4
+ fastapi[all] uvicorn