Izdota pirmā FastAPI versija 2018. gada beigās, un kopš tā laika tā arvien vairāk tiek izmantota daudzās lietojumprogrammās ražošanā. (skatīt FastAPI tīmekļa vietni). Tas ir to, ko mēs izmantojam NLP mākoņa fonā. Tas ir lielisks veids, kā viegli un efektīvi apkalpot mūsu simtiem dabiskās valodas apstrādes modeļu, kas paredzēti būtību ieguvei (NER), teksta klasifikācijai, noskaņojuma analīzei, jautājumu analīzei un datu apstrādei. atbilžu sniegšanai, apkopošanai... Mēs atklājām, ka FastAPI ir lielisks veids, kā apkalpot uz transformatoriem balstītus dziļos mācīšanās modeļus.
Šajā rakstā mēs domājām, ka būtu interesanti parādīt, kā mēs īstenojam dabiskās valodas apstrādes API, kas balstīts uz izmantojot FastAPI, balstoties uz sejas apskāvienu transformatoriem.
Pirms FastAPI mēs pamatā izmantojām Django Rest Framework mūsu Python API, taču mēs ātri vien sākām izmantot FastAPI ieinteresēja šādu iemeslu dēļ:
Šie lieliskie veiktspējas rādītāji padara FastAPI lieliski piemērotu mašīnmācīšanās API, kas apkalpo uz transformatoriem balstītiem modeļiem, piemēram, mūsu modeļiem.
Lai FastAPI varētu darboties, mēs to savienojam ar Uvicorn ASGI serveri, kas ir mūsdienīgs veids, kā to izmantot. dabiski apstrādāt asinhronos Python pieprasījumus ar asyncio. Jūs varat vai nu izlemt instalēt FastAPI ar Uvicorn manuāli vai lejupielādēt gatavu Docker attēlu. Parādīsim vispirms manuālo instalāciju:
pip install fastapi[all]
Tad varat sākt to ar:
uvicorn main:app
FastAPI radītājs Sebastjans Ramirezs (Sebastián Ramírez) piedāvā vairākus lietošanai gatavus Docker attēlus, kas padara to ļoti noderīgu. viegli izmantot FastAPI ražošanā. Uvicorn + Gunicorn + FastAPI attēls izmanto Gunicorn priekšrocības, lai paralēli izmantotu vairākus procesus. (skatīt attēlu šeit). Galu galā, pateicoties Uvicorn jūs varat apstrādāt vairākus FastAPI gadījumus vienā Python procesā, un, pateicoties Gunicorn varat radīt vairākus Python procesus.
Jūsu FastAPI lietojumprogramma tiks automātiski palaista, startējot Docker konteineru ar šādu:
docker run.
Ir svarīgi pareizi izlasīt šo Docker attēlu dokumentāciju, jo ir daži iestatījumi, kurus jūs
piemēram, Gunicorn izveidoto paralēlo procesu skaitu. Pēc noklusējuma,
attēlā tiek radīts tik daudz procesu, cik daudz CPU kodolu ir jūsu datorā. Bet, ja ir prasīgs
mašīnmācīšanās modeļiem, piemēram, dabiskās valodas apstrādes transformatoriem, tas var ātri novest pie desmitiem GB izmantotās atmiņas. Viens
stratēģija būtu izmantot Gunicorn opciju. (--preload), lai ielādētu
modeli atmiņā ielādēt tikai vienu reizi un kopīgot to starp visiem FastAPI Python procesiem. Cita iespēja būtu
ir ierobežot Gunicorn procesu skaitu. Abiem ir priekšrocības un trūkumi, bet tas ir ārpus šī
šī raksta jomu.
Teksta klasifikācija ir process, kurā nosaka, par ko tekstā ir runa (Telpa? Bizness? Par pārtiku?...). Sīkāka informācija par tekstu klasifikācija šeit.
Mēs vēlamies izveidot API galapunktu, kas veic teksta klasifikāciju, izmantojot Facebook lietotni Bart Large MNLI. modeli, kas ir iepriekš apmācīts modelis, kura pamatā ir "apskāviena sejas" transformatori, kas ir lieliski piemēroti teksta klasificēšanai. teksta klasifikācijai.
Mūsu API galapunkts kā ievades datus pieņems teksta fragmentu kopā ar iespējamām kategorijām (ko sauc par etiķetēm), un katrai kategorijai atgriezīs punktu skaitu (jo augstāks, jo lielāka varbūtība).
Mēs pieprasīsim galapunktu, izmantojot šādus POST pieprasījumus:
curl "https://api.nlpcloud.io/v1/bart-large-mnli/classification" \
-H "Authorization: Token e7f6539e5a5d7a16e15" \
-X POST -d '{
"text":"John Doe is a Go Developer at Google. He has been working there for 10 years and has been awarded employee of the year.",
"labels":["job", "nature", "space"]
}'
Un pretī mēs saņemtu šādu atbildi:
{
"labels": [
"job",
"space",
"nature"
],
"scores": [
0.9258803129196167,
0.19384843111038208,
0.010988432914018631
]
}
Šeit ir aprakstīts, kā to panākt, izmantojot FastAPI un transformatorus:
from fastapi import FastAPI
from pydantic import BaseModel, constr, conlist
from typing import List
from transformers import pipeline
classifier = pipeline("zero-shot-classification",
model="facebook/bart-large-mnli")
app = FastAPI()
class UserRequestIn(BaseModel):
text: constr(min_length=1)
labels: conlist(str, min_items=1)
class ScoredLabelsOut(BaseModel):
labels: List[str]
scores: List[float]
@app.post("/classification", response_model=ScoredLabelsOut)
def read_classification(user_request_in: UserRequestIn):
return classifier(user_request_in.text, user_request_in.labels)
Pirmkārt, mēs ielādējam Facebook Bart Large MNLI no Hugging Face repozitorija, un. pareizi inicializējam to klasifikācijas vajadzībām, pateicoties Transformer Pipeline:
classifier = pipeline("zero-shot-classification",
model="facebook/bart-large-mnli")
Un vēlāk mēs izmantojam šo modeli, to darot:
classifier(user_request_in.text, user_request_in.labels)
Otra svarīga lieta: mēs veicam datu validāciju, pateicoties Pydantic. Pydantic liek jums
iepriekš deklarēt jūsu API ieejas un izejas formātu, kas ir lieliski no dokumentācijas viedokļa.
viedokļa, bet arī tāpēc, ka tas ierobežo iespējamās kļūdas. Go programmā jūs darītu gandrīz to pašu.
ar JSON atdalīšanu, izmantojot struktūras. Šeit ir vienkāršs veids, kā
deklarēt, ka laukā "text" jābūt vismaz 1 rakstzīmei: constr(min_length=1).
Turpmāk ir norādīts, ka etiķešu ievades sarakstam sarakstā jābūt vienam elementam:
conlist(str,
min_items=1).
Šī rindiņa nozīmē, ka izejas laukam "etiķetes" ir jābūt virkņu sarakstam: List[str].
Un tas nozīmē, ka vērtējumam ir jābūt peldošo punktu sarakstam: List[float].
Ja modelis atgriež rezultātus, kas neatbilst šim formātam, FastAPI automātiski ziņo par kļūdu.
class UserRequestIn(BaseModel):
text: constr(min_length=1)
labels: conlist(str, min_items=1)
class ScoredLabelsOut(BaseModel):
labels: List[str]
scores: List[float]
Visbeidzot, ar šādu dekoratoru var viegli norādīt, ka pieņemat tikai POST pieprasījumus konkrētā galapunktā:
@app.post("/entities", response_model=EntitiesOut).
Varat veikt daudz sarežģītākas validēšanas darbības, piemēram, kompozīciju. Piemēram, pieņemsim, ka
jūs veicat nosaukto būtņu atpazīšanu (NER), tātad jūsu modelis atgriež būtņu sarakstu. Katra vienība
būtu 4 lauki: text, type, start un position. Lūk, kā jūs to varētu izdarīt:
class EntityOut(BaseModel):
start: int
end: int
type: str
text: str
class EntitiesOut(BaseModel):
entities: List[EntityOut]
@app.post("/entities", response_model=EntitiesOut)
# [...]
Līdz šim mēs ļāvām Pydantic veikt validāciju. Lielākajā daļā gadījumu tas darbojas, bet dažreiz var būt nepieciešams dinamiski radīt kļūdu, pamatojoties uz sarežģītiem nosacījumiem, kurus nav iespējams apstrādāt ar Pydantic. Piemēram, ja vēlaties manuāli atgriezt HTTP 400 kļūdu, varat rīkoties šādi:
from fastapi import HTTPException
raise HTTPException(status_code=400,
detail="Your request is malformed")
Protams, jūs varat darīt daudz vairāk!
Ja izmantojat FastAPI aiz reversā starpniekservera, visticamāk, jums būs jāmaina saknes ceļš.
Grūtākais ir tas, ka aiz reversā starpniekservera lietojumprogramma nezina visu URL ceļu, tāpēc mums ir skaidri jānorāda, kurš tas ir.
Piemēram, šeit pilns URL uz mūsu galapunktu var nebūt vienkārši šāds. /classification. Bet tas varētu būt kaut kas līdzīgs. /api/v1/classification. Mēs nevēlamies kodēt šo pilno URL adresi, lai
mūsu API kods būtu brīvi saistīts ar pārējo lietojumprogrammas daļu. Mēs varētu rīkoties šādi:
app = FastAPI(root_path="/api/v1")
Vai arī, palaižot Uvicorn, varat tam nodot parametru:
uvicorn main:app --root-path /api/v1
Es ceru, ka mēs veiksmīgi parādījām, cik ērts FastAPI var būt dabiskās valodas apstrādes API. Pydantic padara kodu ļoti izteiksmīgs un mazāk pakļauts kļūdām.
FastAPI ir lieliska veiktspēja un ļauj izmantot Python asyncio no kastes, kas ir lieliski. sarežģītiem mašīnmācīšanās modeļiem, piemēram, uz Transformer balstītiem dabiskās valodas apstrādes modeļiem. Mēs esam izmantojuši FastAPI NLP Cloud gandrīz 1 gadu, un līdz šim nekad neesam bijuši vīlušies.
Ja rodas kādi jautājumi, lūdzu, nekautrējieties jautāt, būs prieks komentēt!
Julien Salinas
NLP Cloud tehniskais direktors