Merge pull request #5 from BoardWare-Genius/config

feat: configuration
This commit is contained in:
Dan218
2024-04-30 15:45:38 +08:00
committed by GitHub
17 changed files with 196 additions and 101 deletions

View File

@ -9,8 +9,49 @@
| python | uvicorn | https://www.uvicorn.org/ | pip install "uvicorn[standard]" |
| python | SpeechRecognition | https://pypi.org/project/SpeechRecognition/ | pip install SpeechRecognition |
| python | gtts | https://pypi.org/project/gTTS/ | pip install gTTS |
| python | PyYAML | https://pypi.org/project/PyYAML/ | pip install PyYAML |
| python | injector | https://github.com/python-injector/injector | pip install injector |
## Start
Dev rh
```bash
uvicorn main:app --reload
```
## Configuration
```yaml
tesou:
url: http://120.196.116.194:48891/chat/
TokenIDConverter:
token_path: src/asr/resources/models/token_list.pkl
unk_symbol: <unk>
CharTokenizer:
symbol_value:
space_symbol: <space>
remove_non_linguistic_symbols: false
WavFrontend:
cmvn_file: src/asr/resources/models/am.mvn
frontend_conf:
fs: 16000
window: hamming
n_mels: 80
frame_length: 25
frame_shift: 10
lfr_m: 7
lfr_n: 6
filter_length_max: -.inf
dither: 0.0
Model:
model_path: src/asr/resources/models/model.onnx
use_cuda: false
CUDAExecutionProvider:
device_id: 0
arena_extend_strategy: kNextPowerOfTwo
cudnn_conv_algo_search: EXHAUSTIVE
do_copy_in_default_stream: true
batch_size: 3
```

View File

@ -4,3 +4,5 @@ pip install fastapi
pip install python-multipart
pip install "uvicorn[standard]"
pip install SpeechRecognition
pip install PyYAML
pip install injector

57
main.py
View File

@ -1,59 +1,4 @@
from typing import Annotated, Union
from fastapi import FastAPI, Request, status, Form
from fastapi.responses import JSONResponse
from src.dotchain.runtime.interpreter import program_parser
from src.dotchain.runtime.tokenizer import Tokenizer
from src.dotchain.runtime.runtime import Runtime
from src.blackbox.blackbox_factory import BlackboxFactory
import uvicorn
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
blackbox_factory = BlackboxFactory()
@app.post("/")
async def blackbox(blackbox_name: Union[str, None] = None, request: Request = None):
if not blackbox_name:
return await JSONResponse(content={"error": "blackbox_name is required"}, status_code=status.HTTP_400_BAD_REQUEST)
try:
box = blackbox_factory.create_blackbox(blackbox_name)
except ValueError:
return await JSONResponse(content={"error": "value error"}, status_code=status.HTTP_400_BAD_REQUEST)
return await box.fast_api_handler(request)
def read_form_image(request: Request):
async def inner(field: str):
print(field)
return "image"
return inner
def read_form_text(request: Request):
def inner(field: str):
print(field)
return "text"
return inner
@app.post("/workflows")
async def workflows(script: Annotated[str, Form()], request: Request=None):
dsl_runtime = Runtime(exteral_fun={"print": print,
'read_form_image': read_form_image(request),
"read_form_text": read_form_text(request)})
t = Tokenizer()
t.init(script)
ast = program_parser(t)
ast.exec(dsl_runtime)
if __name__ == "__main__":
uvicorn.run("main:app", host="0.0.0.0", port=8000, log_level="info")
uvicorn.run("router:app", host="0.0.0.0", port=8000, log_level="info")

35
router.py Normal file
View File

@ -0,0 +1,35 @@
from typing import Annotated, Union
from fastapi import FastAPI, Request, status, Form
from fastapi.responses import JSONResponse
from src.dotchain.runtime.interpreter import program_parser
from src.dotchain.runtime.tokenizer import Tokenizer
from src.dotchain.runtime.runtime import Runtime
from src.blackbox.blackbox_factory import BlackboxFactory
import uvicorn
from fastapi.middleware.cors import CORSMiddleware
from injector import Injector
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
injector = Injector()
blackbox_factory = injector.get(BlackboxFactory)
@app.post("/")
async def blackbox(blackbox_name: Union[str, None] = None, request: Request = None):
if not blackbox_name:
return await JSONResponse(content={"error": "blackbox_name is required"}, status_code=status.HTTP_400_BAD_REQUEST)
try:
box = blackbox_factory.call_blackbox(blackbox_name)
except ValueError:
return await JSONResponse(content={"error": "value error"}, status_code=status.HTTP_400_BAD_REQUEST)
return await box.fast_api_handler(request)

View File

@ -7,11 +7,13 @@ from fastapi.responses import JSONResponse
from ..asr.rapid_paraformer.utils import read_yaml
from ..asr.rapid_paraformer import RapidParaformer
from .blackbox import Blackbox
from injector import singleton
@singleton
class ASR(Blackbox):
def __init__(self, *args, **kwargs) -> None:
config = read_yaml(args[0])
def __init__(self, path = ".env.yaml") -> None:
config = read_yaml(path)
self.paraformer = RapidParaformer(config)
def __call__(self, *args, **kwargs):

View File

@ -1,11 +1,18 @@
from fastapi import Request, Response,status
from fastapi.responses import JSONResponse
from injector import inject, singleton
from .asr import ASR
from .tesou import Tesou
from .tts import TTS
from .blackbox import Blackbox
@singleton
class AudioChat(Blackbox):
def __init__(self, asr, gpt, tts):
@inject
def __init__(self, asr: ASR, gpt: Tesou, tts: TTS):
self.asr = asr
self.gpt = gpt
self.tts = tts

View File

@ -3,9 +3,10 @@ from fastapi.responses import JSONResponse
import speech_recognition as sr
import filetype
import io
from injector import singleton
from .blackbox import Blackbox
@singleton
class AudioToText(Blackbox):
def __call__(self, *args, **kwargs):

View File

@ -9,43 +9,40 @@ from .tesou import Tesou
from .fastchat import Fastchat
from .g2e import G2E
from .text_and_image import TextAndImage
from injector import inject, singleton
@singleton
class BlackboxFactory:
models = {}
def __init__(self) -> None:
self.tts = TTS()
self.asr = ASR(".env.yaml")
self.sentiment = Sentiment()
self.audio_to_text = AudioToText()
self.text_to_audio = TextToAudio()
self.tesou = Tesou()
self.fastchat = Fastchat()
self.audio_chat = AudioChat(self.asr, self.tesou, self.tts)
self.g2e = G2E()
self.text_and_image = TextAndImage()
@inject
def __init__(self,
audio_to_text: AudioToText,
text_to_audio: TextToAudio,
asr: ASR,
tts: TTS,
sentiment_engine: Sentiment,
tesou: Tesou,
fastchat: Fastchat,
audio_chat: AudioChat,
g2e: G2E,
text_and_image:TextAndImage ) -> None:
self.models["audio_to_text"] = audio_to_text
self.models["text_to_audio"] = text_to_audio
self.models["asr"] = asr
self.models["tts"] = tts
self.models["sentiment_engine"] = sentiment_engine
self.models["tesou"] = tesou
self.models["fastchat"] = fastchat
self.models["audio_chat"] = audio_chat
self.models["g2e"] = g2e
self.models["text_and_image"] = text_and_image
def __call__(self, *args, **kwargs):
return self.processing(*args, **kwargs)
def create_blackbox(self, blackbox_name: str) -> Blackbox:
if blackbox_name == "audio_to_text":
return self.audio_to_text
if blackbox_name == "text_to_audio":
return self.text_to_audio
if blackbox_name == "asr":
return self.asr
if blackbox_name == "tts":
return self.tts
if blackbox_name == "sentiment_engine":
return self.sentiment
if blackbox_name == "tesou":
return self.tesou
if blackbox_name == "fastchat":
return self.fastchat
if blackbox_name == "audio_chat":
return self.audio_chat
if blackbox_name == "g2e":
return self.g2e
if blackbox_name == 'text_and_image':
return self.text_and_image
def call_blackbox(self, blackbox_name: str) -> Blackbox:
model = self.models.get(blackbox_name)
if model is None:
raise ValueError("Invalid blockbox type")
return model

View File

@ -6,8 +6,10 @@ from fastapi.responses import JSONResponse
from .blackbox import Blackbox
from lagent.llms.lmdepoly_wrapper import LMDeployClient
from lagent.llms.meta_template import INTERNLM2_META as META
from injector import singleton
class Sentiment(Blackbox):
@singleton
class Emotion(Blackbox):
def __init__(self, model_name, model_url) -> None:
self.model = LMDeployClient(

View File

@ -7,6 +7,8 @@ from .blackbox import Blackbox
import requests
import json
from injector import singleton
@singleton
class Fastchat(Blackbox):
def __call__(self, *args, **kwargs):

View File

@ -7,7 +7,8 @@ from .blackbox import Blackbox
import requests
import json
from openai import OpenAI
from injector import singleton
@singleton
class G2E(Blackbox):
def __call__(self, *args, **kwargs):

View File

@ -6,7 +6,8 @@ from fastapi.responses import JSONResponse
from ..sentiment_engine.sentiment_engine import SentimentEngine
from .blackbox import Blackbox
from injector import singleton
@singleton
class Sentiment(Blackbox):
def __init__(self) -> None:

View File

@ -2,11 +2,20 @@ from typing import Any, Coroutine
from fastapi import Request, Response, status
from fastapi.responses import JSONResponse
from injector import inject
from ..configuration import TesouConf
from .blackbox import Blackbox
import requests
from injector import singleton
@singleton
class Tesou(Blackbox):
url: str
@inject
def __init__(self, tesou_config: TesouConf):
self.url = tesou_config.url
def __call__(self, *args, **kwargs):
return self.processing(*args, **kwargs)
@ -17,12 +26,11 @@ class Tesou(Blackbox):
# 用户输入的数据格式为:[{"id": "123", "prompt": "叉烧饭,帮我查询叉烧饭的介绍"}]
def processing(self, id, prompt) -> str:
url = 'http://120.196.116.194:48891/chat/'
message = {
"user_id": id,
"prompt": prompt,
}
response = requests.post(url, json=message)
response = requests.post(self.url, json=message)
return response.json()
async def fast_api_handler(self, request: Request) -> Response:

View File

@ -4,7 +4,8 @@ from fastapi import Request, Response, status
from fastapi.responses import JSONResponse
from .blackbox import Blackbox
from injector import singleton
@singleton
class TextAndImage(Blackbox):
def __call__(self, *args, **kwargs):

View File

@ -3,7 +3,8 @@ from fastapi.responses import JSONResponse
from .blackbox import Blackbox
from gtts import gTTS
from io import BytesIO
from injector import singleton
@singleton
class TextToAudio(Blackbox):
def __call__(self, *args, **kwargs):

View File

@ -6,7 +6,9 @@ from fastapi import Request, Response, status
from fastapi.responses import JSONResponse
from .blackbox import Blackbox
from ..tts.tts_service import TTService
from injector import singleton
@singleton
class TTS(Blackbox):
def __init__(self, *args, **kwargs) -> None:

47
src/configuration.py Normal file
View File

@ -0,0 +1,47 @@
from dataclasses import dataclass
from injector import Injector, inject
import yaml
import sys
class Configuration():
@inject
def __init__(self) -> None:
config_file_path = ""
try:
config_file_path = sys.argv[1]
except:
config_file_path = ".env.yaml"
with open(config_file_path) as f:
cfg = yaml.load(f, Loader=yaml.FullLoader)
self.cfg = cfg
def getDict(self):
return self.cfg
"""
# yaml 檔中的路徑 get("aaa.bbb.ccc")
aaa:
bbb:
ccc: "hello world"
"""
def get(self, path: str | list[str], cfg: dict = None):
if isinstance(path, str):
if cfg is None:
cfg = self.cfg
return self.get(path.split("."), cfg)
lenght = len(path)
if lenght == 0 or not isinstance(cfg, dict):
return None
if lenght == 1:
return cfg.get(path[0])
return self.get(path[1:], cfg.get(path[0]))
class TesouConf():
url: str
@inject
def __init__(self,config: Configuration) -> None:
self.url = config.get("tesou.url")