FastAPI'nin ilk sürümü yayınlandı 2018'in sonunda ve o zamandan beri üretimdeki birçok uygulamada giderek daha fazla kullanılıyor (FastAPI'nin web sitesine bakın). İşte bu. NLP Cloud'da kaputun arkasında kullandığımız şey. Bu, müşterilerimize kolay ve verimli bir şekilde hizmet vermenin harika bir yoludur. yüzlerce Doğal Dil İşleme modeli, varlık çıkarma (NER), metin sınıflandırma, duygu analizi, soru cevaplama, özetleme... FastAPI'nin, transformatör tabanlı derinlemesine hizmet vermek için harika bir yol olduğunu gördük öğrenme modelleri.
Bu makalede, size Doğal Dil İşleme API'sini nasıl uyguladığımızı göstermenin ilginç olacağını düşündük FastAPI ile Hugging Face transformatörleri üzerine.
FastAPI'den önce, Python API'lerimiz için esasen Django Rest Framework kullanıyorduk, ancak hızlı bir şekilde aşağıdaki nedenlerden dolayı FastAPI ile ilgilenmektedir:
Bu harika performanslar FastAPI'yi hizmet veren makine öğrenimi API'leri için mükemmel şekilde uygun hale getirir bizimki gibi transformatör tabanlı modeller.
FastAPI'nin çalışması için, onu Uvicorn ASGI sunucusuyla birleştiriyoruz, bu da aşağıdakileri yapmanın modern yoludur asyncio ile asenkron Python isteklerini yerel olarak işleyin. Şuna karar verebilirsiniz Uvicorn ile FastAPI'yi manuel olarak kurun veya kullanıma hazır bir Docker imajı indirin. Hadi gösterelim önce manuel kurulum:
pip install fastapi[all]
O zaman şöyle başlayabilirsiniz:
uvicorn main:app
FastAPI'nin yaratıcısı Sebastián Ramírez, kullanıma hazır birkaç Docker görüntüsü sağlayarak FastAPI'yi üretimde kullanmak kolay. Uvicorn + Gunicorn + FastAPI görüntü, birkaç işlemi paralel olarak kullanmak için Gunicorn'dan yararlanır (resmi burada görebilirsiniz). Sonunda, teşekkürler Uvicorn sayesinde aynı Python süreci içinde birden fazla FastAPI örneğini işleyebilirsiniz ve Gunicorn sayesinde birkaç Python süreci oluşturabilirsiniz.
FastAPI uygulamanız, Docker konteynerini aşağıdaki şekilde başlatırken otomatik olarak başlayacaktır:
docker run.
Bu Docker görüntülerinin belgelerini düzgün bir şekilde okumak önemlidir, çünkü bazı ayarlar vardır
örneğin Gunicorn tarafından oluşturulan paralel süreçlerin sayısı gibi ayarlamalar yapmak isteyebilirsiniz. Varsayılan olarak,
görüntü, makinenizdeki CPU çekirdeği sayısı kadar işlem ortaya çıkarır. Ancak zorlu durumlarda
Doğal Dil İşleme Transformatörleri gibi makine öğrenimi modelleri, hızlı bir şekilde onlarca GB bellek kullanımına yol açabilir. Bir
stratejisi Gunicorn seçeneğinden yararlanmak olacaktır (--preload), yüklemek için
modelinizi bellekte yalnızca bir kez tutun ve tüm FastAPI Python süreçleri arasında paylaşın. Başka bir seçenek de
Gunicorn süreçlerinin sayısını sınırlamak olabilir. Her ikisinin de avantajları ve dezavantajları var, ancak bu konunun ötesinde
bu makalenin kapsamı.
Metin sınıflandırma, bir metin parçasının ne hakkında konuştuğunu belirleme sürecidir (Uzay? İş? Yemek?...). Metin hakkında daha fazla bilgi sınıflandırma burada.
Facebook'un Bart Large MNLI'sini kullanarak metin sınıflandırması yapan bir API uç noktası oluşturmak istiyoruz Hugging Face transformatörlerine dayalı önceden eğitilmiş bir model olan model, metin için mükemmel bir şekilde uygundur sınıflandırma.
API uç noktamız, potansiyel kategorilerle (etiket olarak adlandırılır) birlikte bir metin parçasını girdi olarak alacaktır, ve her kategori için bir puan döndürecektir (ne kadar yüksekse, o kadar olasıdır).
Uç noktayı bu şekilde POST istekleri ile talep edeceğiz:
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"]
}'
Ve karşılığında şöyle bir yanıt alırdık:
{
"labels": [
"job",
"space",
"nature"
],
"scores": [
0.9258803129196167,
0.19384843111038208,
0.010988432914018631
]
}
İşte FastAPI ve Transformers ile bunu nasıl başaracağınız:
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)
İlk olarak: Facebook'un Bart Large MNLI'sini Hugging Face deposundan yüklüyoruz ve Transformer Pipeline sayesinde sınıflandırma amacıyla düzgün bir şekilde başlatılması:
classifier = pipeline("zero-shot-classification",
model="facebook/bart-large-mnli")
Ve daha sonra bunu yaparak modeli kullanıyoruz:
classifier(user_request_in.text, user_request_in.labels)
İkinci önemli şey: Pydantic sayesinde veri doğrulaması yapıyoruz. Pydantic sizi şunları yapmaya zorluyor
API'niz için girdi ve çıktı formatını önceden beyan edin, bu bir dokümantasyon açısından harikadır
ama aynı zamanda potansiyel hataları sınırladığı için. Go'da da hemen hemen aynı şeyi yapardınız
yapılarla JSON unmarshalling ile. İşte kolay bir yol
"metin" alanının en az 1 karaktere sahip olması gerektiğini beyan edin: constr(min_length=1).
Ve aşağıdakiler, etiketlerin giriş listesinin listede bir eleman içermesi gerektiğini belirtir:
conlist(str,
min_items=1).
Bu satır, "labels" çıktı alanının dizelerden oluşan bir liste olması gerektiği anlamına gelir: List[str].
Bu da puanların kayan noktaların bir listesi olması gerektiği anlamına gelir: List[float].
Eğer model bu formata uymayan sonuçlar döndürürse, FastAPI otomatik olarak bir hata verecektir.
class UserRequestIn(BaseModel):
text: constr(min_length=1)
labels: conlist(str, min_items=1)
class ScoredLabelsOut(BaseModel):
labels: List[str]
scores: List[float]
Son olarak, aşağıdaki dekoratör, belirli bir uç noktada yalnızca POST isteklerini kabul ettiğinizi belirtmenizi kolaylaştırır:
@app.post("/entities", response_model=EntitiesOut).
Örneğin kompozisyon gibi çok daha karmaşık doğrulama işlemleri yapabilirsiniz. Örneğin, diyelim ki
Adlandırılmış Varlık Tanıma (NER) yapıyorsunuz, dolayısıyla modeliniz varlıkların bir listesini döndürüyor. Her varlık
4 alana sahip olacaktır: text, type, start ve position. Bunu şu şekilde yapabilirsiniz:
class EntityOut(BaseModel):
start: int
end: int
type: str
text: str
class EntitiesOut(BaseModel):
entities: List[EntityOut]
@app.post("/entities", response_model=EntitiesOut)
# [...]
Şimdiye kadar, doğrulama işlemini Pydantic'in yapmasına izin verdik. Çoğu durumda işe yarıyor, ancak bazen şunları isteyebilirsiniz tarafından yerel olarak ele alınmayan karmaşık koşullara dayalı olarak bir hatayı dinamik olarak kendiniz yükseltmek için Pydantic. Örneğin, manuel olarak bir HTTP 400 hatası döndürmek istiyorsanız, aşağıdakileri yapabilirsiniz:
from fastapi import HTTPException
raise HTTPException(status_code=400,
detail="Your request is malformed")
Elbette çok daha fazlasını yapabilirsiniz!
FastAPI'yi bir ters proxy arkasında kullanıyorsanız, büyük olasılıkla kök yolu ile oynamanız gerekecektir.
Zor olan şey, bir ters proxy'nin arkasında, uygulamanın tüm URL yolunu bilmemesidir, Bu yüzden hangisinin olduğunu açıkça söylememiz gerekir.
Örneğin burada uç noktamızın tam URL'si basitçe şöyle olmayabilir /classification. Ama şöyle bir şey olabilir /api/v1/classification. için bu tam URL'yi sabit kodlamak istemiyoruz.
API kodumuzun uygulamanın geri kalanıyla gevşek bir şekilde bağlanması. Bunu yapabiliriz:
app = FastAPI(root_path="/api/v1")
Ya da alternatif olarak Uvicorn'u başlatırken ona bir parametre aktarabilirsiniz:
uvicorn main:app --root-path /api/v1
Umarım FastAPI'nin bir Doğal Dil İşleme API'si için ne kadar kullanışlı olabileceğini size başarıyla göstermişizdir. Pydantic kodu yapar çok etkileyici ve daha az hata eğilimli.
FastAPI harika performanslara sahiptir ve Python asyncio'yu kutudan çıkar çıkmaz kullanmayı mümkün kılar, bu harika Transformer tabanlı Doğal Dil İşleme modelleri gibi zorlu makine öğrenimi modelleri için. FastAPI'yi şu amaçlarla kullanıyoruz NLP Cloud'da neredeyse 1 yıl ve şimdiye kadar hiç hayal kırıklığına uğramadık.
Herhangi bir sorunuz varsa, lütfen sormaktan çekinmeyin, yorum yapmaktan memnuniyet duyarız!
Julien Salinas
NLP Cloud'da CTO