Skip to content

Commit 0bcf850

Browse files
authored
Update APIs service (#17)
* new feats * fix requests error * Update README.md
1 parent eff3e39 commit 0bcf850

13 files changed

Lines changed: 357 additions & 30 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Aloha!
22

33
[![License](https://img.shields.io/github/license/QPod/aloha)](https://github.com/QPod/aloha/blob/main/LICENSE)
4-
[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/QPod/aloha/build)](https://github.com/QPod/aloha/actions)
4+
[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/QPod/aloha-python/pip.yml?branch=main)](https://github.com/QPod/aloha-python/actions)
55
[![Join the Gitter Chat](https://img.shields.io/gitter/room/nwjs/nw.js.svg)](https://gitter.im/QPod/)
66
[![PyPI version](https://img.shields.io/pypi/v/aloha)](https://pypi.python.org/pypi/aloha/)
77
[![PyPI Downloads](https://img.shields.io/pypi/dm/aloha)](https://pepy.tech/badge/aloha/)
@@ -21,6 +21,6 @@ Please generously STAR★ our project or donate to us! [![GitHub Starts](https:
2121

2222
## Getting started
2323

24-
```py
24+
```shell
2525
pip install aloha[all]
2626
```

demo/app_common/ainlp/__init__.py

Whitespace-only changes.
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
from typing import List
2+
3+
import torch
4+
from transformers import AutoTokenizer, AutoModel
5+
6+
from aloha.service.streamer import ManagedModel
7+
8+
SEED = 0
9+
torch.manual_seed(SEED)
10+
torch.cuda.manual_seed(SEED)
11+
12+
13+
class TextUnmaskModel:
14+
def __init__(self, max_sent_len=16, model_path="bert-base-uncased"):
15+
self.model_path = model_path
16+
self.tokenizer = AutoTokenizer.from_pretrained(self.model_path)
17+
self.transformer = AutoModel.from_pretrained(self.model_path)
18+
self.transformer.eval()
19+
self.transformer.to(device="cuda")
20+
self.max_sent_len = max_sent_len
21+
22+
def predict(self, batch: List[str]) -> List[str]:
23+
"""predict masked word"""
24+
batch_inputs = []
25+
masked_indexes = []
26+
27+
for text in batch:
28+
tokenized_text = self.tokenizer.tokenize(text)
29+
if len(tokenized_text) > self.max_sent_len - 2:
30+
tokenized_text = tokenized_text[: self.max_sent_len - 2]
31+
32+
tokenized_text = ['[CLS]'] + tokenized_text + ['[SEP]']
33+
tokenized_text += ['[PAD]'] * (self.max_sent_len - len(tokenized_text))
34+
35+
indexed_tokens = self.tokenizer.convert_tokens_to_ids(tokenized_text)
36+
batch_inputs.append(indexed_tokens)
37+
masked_indexes.append(tokenized_text.index('[MASK]'))
38+
39+
tokens_tensor = torch.tensor(batch_inputs).to("cuda")
40+
41+
with torch.no_grad():
42+
# prediction_scores: ``torch.FloatTensor`` of shape ``(batch_size, sequence_length, config.vocab_size)``
43+
prediction_scores = self.transformer(tokens_tensor)[0]
44+
45+
batch_outputs = []
46+
for i in range(len(batch_inputs)):
47+
predicted_index = torch.argmax(prediction_scores[i, masked_indexes[i]]).item()
48+
predicted_token = self.tokenizer.convert_ids_to_tokens(predicted_index)
49+
batch_outputs.append(predicted_token)
50+
51+
return batch_outputs
52+
53+
54+
class ManagedBertModel(ManagedModel):
55+
def init_model(self):
56+
self.model = TextUnmaskModel()
57+
58+
def predict(self, batch):
59+
return self.model.predict(batch)
60+
61+
62+
def test_simple():
63+
tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
64+
model = AutoModel.from_pretrained("bert-base-uncased")
65+
inputs = tokenizer("Hello! My name is [MASK]!", return_tensors="pt")
66+
outputs = model(**inputs)
67+
print(outputs)
68+
69+
predicted_index = torch.argmax(outputs[1]).item()
70+
predicted_token = tokenizer.convert_ids_to_tokens(predicted_index)
71+
print(predicted_token)
72+
73+
74+
def test_batch():
75+
batch_text = [
76+
"twinkle twinkle [MASK] star.",
77+
"Happy birthday to [MASK].",
78+
'the answer to life, the [MASK], and everything.'
79+
]
80+
model = TextUnmaskModel()
81+
outputs = model.predict(batch_text)
82+
print(outputs)
83+
84+
85+
if __name__ == "__main__":
86+
test_simple()

demo/app_common/ainlp/test-gpu-async.py

Whitespace-only changes.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from aloha.logger import LOG
2+
from aloha.service.api.v0 import APIHandler
3+
4+
5+
class MultipartHandler(APIHandler):
6+
def response(self, params=None, *args, **kwargs):
7+
LOG.debug(params)
8+
return params
9+
10+
11+
default_handlers = [
12+
# internal API: QueryDB Postgres with sql directly
13+
(r"/api_internal/multipart", MultipartHandler),
14+
]

demo/app_common/debug.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ def main():
66
modules_to_load = [
77
"app_common.api.api_common_sys_info",
88
"app_common.api.api_common_query_postgres",
9+
"app_common.api.api_multipart",
910
]
1011

1112
if 'service' not in SETTINGS.config:

src/aloha/config/paths.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,19 @@ def get_config_files() -> list:
4848

4949
files = files_config.split(',')
5050
ret = []
51+
msgs = []
5152
for f in files:
5253
file = get_config_dir(f)
5354
if not os.path.exists(file):
54-
warnings.warn('Expecting config file [%s] but it does not exists!' % file)
55+
msgs.append('Expecting config file [%s] but it does not exists!' % file)
5556
else:
5657
print(' ---> Loading config file [%s]' % file)
5758
ret.append(os.path.expandvars(f))
5859
if len(ret) == 0:
59-
warnings.warn('No config files set properly, EMPTY config will be used!')
60+
msgs.append('No config files set properly, EMPTY config will be used!')
61+
62+
if len(msgs) > 0:
63+
warnings.warn('\n'.join(msgs))
6064
return ret
6165

6266

src/aloha/encrypt/vault/cyberark.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
from ...logger import LOG
1212

1313
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
14-
requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS += ':HIGHT:!DH:!aNULL'
14+
if hasattr(requests.packages.urllib3.util.ssl_, 'DEFAULT_CIPHERS'):
15+
requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS += ':HIGHT:!DH:!aNULL'
1516

1617

1718
class CyberArkVault(BaseVault, AesEncryptor):

src/aloha/service/api/v0.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@ class APIHandler(AbstractApiHandler, ABC):
1313
}
1414

1515
async def post(self, *args, **kwargs):
16-
body_arguments = self.request_body
17-
kwargs.update(body_arguments)
16+
req_body = self.request_body
17+
18+
if req_body is not None: # body_arguments
19+
kwargs.update(req_body)
1820

1921
resp = dict(code=5200, message=['success'])
2022
try:

src/aloha/service/http/base_api_handler.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def request_body(self) -> dict:
5151
body_arguments: dict = Optional[None]
5252

5353
if content_type.startswith('multipart/form-data'): # only parse files when 'Content-Type' starts with 'multipart/form-data'
54-
body_arguments = self.request.body_arguments
54+
body_arguments = self.request_param # self.request.body_arguments
5555
else:
5656
try:
5757
body = self.request.body.decode('utf-8')
@@ -62,8 +62,16 @@ def request_body(self) -> dict:
6262

6363
@property
6464
def request_param(self) -> dict:
65-
url_arguments: dict = {k: v[0].decode('utf-8') for k, v in self.request.arguments.items()}
66-
return url_arguments
65+
ret: dict = {}
66+
for k, v in self.request.arguments.items():
67+
val = v[0].decode('utf-8')
68+
try:
69+
value = json.loads(val)
70+
except json.JSONDecodeError:
71+
value = val
72+
ret[k] = value
73+
74+
return ret
6775

6876

6977
class DefaultHandler404(AbstractApiHandler):

0 commit comments

Comments
 (0)