Skip to content

Commit 0623ddb

Browse files
Merge branch 'Samagra-Development:restructure' into restructure
2 parents 5318851 + 3f054a4 commit 0623ddb

File tree

10 files changed

+157
-2
lines changed

10 files changed

+157
-2
lines changed

config.json

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,22 @@
11
{
22
"models": [
33
{
4+
"serviceName": "ner",
5+
"modelBasePath": "src/ner/agri_ner_akai/local/.",
6+
"apiBasePath": "ner/agri_ner_akai/local/",
7+
"containerPort": 8000,
8+
"environment": {},
9+
"nginx": [],
10+
"build": true
11+
},
12+
{
413
"serviceName": "word_score",
514
"modelBasePath": "src/search/word_score/local/.",
6-
"apiBasePath": "/search/word_score/local",
15+
"apiBasePath": "/search/word_score/local/",
716
"containerPort": 8000,
817
"environment": {},
918
"nginx": [],
10-
"build": false
19+
"build": true
1120
},
1221
{
1322
"serviceName": "spell_check",

src/ner/README.md

Whitespace-only changes.

src/ner/agri_ner_akai/README.md

Whitespace-only changes.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Use an official Python runtime as a parent image
2+
FROM python:3.9-slim
3+
4+
WORKDIR /app
5+
6+
7+
#install requirements
8+
COPY requirements.txt requirements.txt
9+
RUN pip3 install -r requirements.txt
10+
11+
# Copy the rest of the application code to the working directory
12+
COPY . /app/
13+
EXPOSE 8000
14+
# Set the entrypoint for the container
15+
CMD ["hypercorn", "--bind", "0.0.0.0:8000", "api:app"]
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
## NER:
2+
3+
4+
### Purpose :
5+
Model to detect
6+
- crops
7+
- pests
8+
- seed type
9+
10+
11+
### Testing the model deployment :
12+
To run for testing just the Hugging Face deployment for grievence recognition, you can follow the following steps :
13+
14+
- Git clone the repo
15+
- Go to current folder location i.e. ``` cd /src/ner/agri_ner_akai/local ```
16+
- Create docker image file and test the api:
17+
```
18+
docker build -t testmodel .
19+
docker run -p 8000:8000 testmodel
20+
curl -X POST -H "Content-Type: application/json" -d '{"text": "What are tomatoes and potaotes that are being attacked by aphids? "}' http://localhost:8000/
21+
```
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from .request import ModelRequest
2+
from .request import Model

src/ner/agri_ner_akai/local/api.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from model import Model
2+
from request import ModelRequest
3+
from quart import Quart, request, jsonify
4+
import aiohttp
5+
6+
app = Quart(__name__)
7+
8+
model = None
9+
10+
@app.before_serving
11+
async def startup():
12+
app.client = aiohttp.ClientSession()
13+
global model
14+
model = Model(app)
15+
16+
@app.route('/', methods=['POST'])
17+
async def embed():
18+
global model
19+
data = await request.get_json()
20+
req = ModelRequest(**data)
21+
entities = await model.inference(req)
22+
return jsonify(entities) # Convert the list of entities to JSON format
23+
24+
if __name__ == "__main__":
25+
app.run()
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
from transformers import pipeline
2+
from request import ModelRequest
3+
4+
class Model():
5+
def __new__(cls, context):
6+
cls.context = context
7+
if not hasattr(cls, 'instance'):
8+
cls.instance = super(Model, cls).__new__(cls)
9+
cls.nlp_ner = pipeline("ner", model="GautamR/akai_ner", tokenizer="GautamR/akai_ner")
10+
return cls.instance
11+
12+
async def inference(self, request: ModelRequest):
13+
entities = self.nlp_ner(request.text)
14+
return self.aggregate_entities(request.text, entities)
15+
16+
@staticmethod
17+
def aggregate_entities(sentence, entity_outputs):
18+
aggregated_entities = []
19+
current_entity = None
20+
21+
for entity in entity_outputs:
22+
entity_type = entity["entity"].split("-")[-1]
23+
24+
# Handle subwords
25+
if entity["word"].startswith("##"):
26+
# If we encounter an I-PEST or any other I- entity
27+
if "I-" in entity["entity"]:
28+
if current_entity: # Add previous entity
29+
aggregated_entities.append(current_entity)
30+
31+
word_start = sentence.rfind(" ", 0, entity["start"]) + 1
32+
word_end = sentence.find(" ", entity["end"])
33+
if word_end == -1:
34+
word_end = len(sentence)
35+
36+
current_entity = {
37+
"entity_group": entity_type,
38+
"score": float(entity["score"]),
39+
"word": sentence[word_start:word_end].replace('.','').replace('?',''),
40+
"start": float(word_start),
41+
"end": float(word_end)
42+
}
43+
aggregated_entities.append(current_entity)
44+
current_entity = None
45+
46+
else:
47+
# If it's a subword but not an I- entity
48+
current_entity["word"] += entity["word"][2:]
49+
current_entity["end"] = entity["end"]
50+
current_entity["score"] = float((current_entity["score"] + entity["score"]) / 2) # averaging scores
51+
52+
# Handle full words
53+
else:
54+
if current_entity:
55+
aggregated_entities.append(current_entity)
56+
57+
current_entity = {
58+
"entity_group": entity_type,
59+
"score": float(entity["score"]),
60+
"word": entity["word"],
61+
"start": float(entity["start"]),
62+
"end": float(entity["end"])
63+
}
64+
65+
if current_entity:
66+
aggregated_entities.append(current_entity)
67+
68+
return aggregated_entities
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import requests
2+
import json
3+
4+
5+
class ModelRequest():
6+
def __init__(self, text):
7+
self.text = text
8+
9+
def to_json(self):
10+
return json.dumps(self, default=lambda o: o.__dict__,
11+
sort_keys=True, indent=4)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
torch==2.0.1 --index-url https://download.pytorch.org/whl/cpu
2+
transformers
3+
quart
4+
aiohttp

0 commit comments

Comments
 (0)