Skip to content

[Draft] Experiment using api-inference-community for inference definitions #82

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

extras = {}

extras["st"] = ["sentence_transformers==2.7.0"]
extras["st"] = ["hf_api_sentence_transformers==0.0.1"]
extras["diffusers"] = ["diffusers==0.30.0", "accelerate==0.33.0"]
# Includes `peft` as PEFT requires `torch` so having `peft` as a core dependency
# means that `torch` will be installed even if the `torch` extra is not specified.
Expand Down
33 changes: 9 additions & 24 deletions src/huggingface_inference_toolkit/sentence_transformers_utils.py
Original file line number Diff line number Diff line change
@@ -1,51 +1,38 @@
import importlib.util

_sentence_transformers = importlib.util.find_spec("sentence_transformers") is not None
_sentence_transformers = importlib.util.find_spec("hf_api_sentence_transformers") is not None


def is_sentence_transformers_available():
return _sentence_transformers


if is_sentence_transformers_available():
from sentence_transformers import CrossEncoder, SentenceTransformer, util
from hf_api_sentence_transformers import FeatureExtractionPipeline
from hf_api_sentence_transformers import SentenceSimilarityPipeline as SentenceSimilarityPipelineImpl


class SentenceSimilarityPipeline:
def __init__(self, model_dir: str, device: str = None, **kwargs): # needs "cuda" for GPU
self.model = SentenceTransformer(model_dir, device=device, **kwargs)
self.model = SentenceSimilarityPipelineImpl(model_dir)

def __call__(self, inputs=None):
embeddings1 = self.model.encode(
inputs["source_sentence"], convert_to_tensor=True
)
embeddings2 = self.model.encode(inputs["sentences"], convert_to_tensor=True)
similarities = util.pytorch_cos_sim(embeddings1, embeddings2).tolist()[0]
return {"similarities": similarities}
return {"similarities": self.model(inputs)}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm doing this for backwards compatibility, but note that this is inconsistent with the other APIs and https://github.com/huggingface/huggingface.js/blob/main/packages/tasks/src/tasks/sentence-similarity/inference.ts



class SentenceEmbeddingPipeline:
def __init__(self, model_dir: str, device: str = None, **kwargs): # needs "cuda" for GPU
self.model = SentenceTransformer(model_dir, device=device, **kwargs)
self.model = FeatureExtractionPipeline(model_dir)

def __call__(self, inputs):
embeddings = self.model.encode(inputs).tolist()
return {"embeddings": embeddings}

return {"embeddings": self.model(inputs)}

class RankingPipeline:
def __init__(self, model_dir: str, device: str = None, **kwargs): # needs "cuda" for GPU
self.model = CrossEncoder(model_dir, device=device, **kwargs)

def __call__(self, inputs):
scores = self.model.predict(inputs).tolist()
return {"scores": scores}


SENTENCE_TRANSFORMERS_TASKS = {
"sentence-similarity": SentenceSimilarityPipeline,
"sentence-embeddings": SentenceEmbeddingPipeline,
"sentence-ranking": RankingPipeline,
#"sentence-ranking": RankingPipeline, # To be implemented
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removing for now as there's not one

}


Expand All @@ -59,6 +46,4 @@ def get_sentence_transformers_pipeline(task=None, model_dir=None, device=-1, **k
raise ValueError(
f"Unknown task {task}. Available tasks are: {', '.join(SENTENCE_TRANSFORMERS_TASKS.keys())}"
)
return SENTENCE_TRANSFORMERS_TASKS[task](
model_dir=model_dir, device=device, **kwargs
)
return SENTENCE_TRANSFORMERS_TASKS[task](model_dir=model_dir)
32 changes: 16 additions & 16 deletions tests/unit/test_sentence_transformers.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,19 @@ def test_sentence_similarity():
assert isinstance(res["similarities"], list)


@require_torch
def test_sentence_ranking():
with tempfile.TemporaryDirectory() as tmpdirname:
storage_dir = _load_repository_from_hf("cross-encoder/ms-marco-MiniLM-L-6-v2", tmpdirname)
pipe = get_sentence_transformers_pipeline("sentence-ranking", storage_dir.as_posix())
res = pipe(
[
["Lets create an embedding", "Lets create an embedding"],
["Lets create an embedding", "Lets create an embedding"],
]
)
assert isinstance(res["scores"], list)
res = pipe(
["Lets create an embedding", "Lets create an embedding"],
)
assert isinstance(res["scores"], float)
#@require_torch
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All other tests pass 🔥

#def test_sentence_ranking():
# with tempfile.TemporaryDirectory() as tmpdirname:
# storage_dir = _load_repository_from_hf("cross-encoder/ms-marco-MiniLM-L-6-v2", tmpdirname)
# pipe = get_sentence_transformers_pipeline("sentence-ranking", storage_dir.as_posix())
# res = pipe(
# [
# ["Lets create an embedding", "Lets create an embedding"],
# ["Lets create an embedding", "Lets create an embedding"],
# ]
# )
# assert isinstance(res["scores"], list)
# res = pipe(
# ["Lets create an embedding", "Lets create an embedding"],
# )
# assert isinstance(res["scores"], float)