mirror of
https://github.com/microsoft/semantic-kernel.git
synced 2026-10-12 02:19:06 +00:00
Python: fixes for hugging face and working integration tests (#4927)
### Motivation and Context <!-- Thank you for your contribution to the semantic-kernel repo! Please help reviewers and future users, providing the following information: 1. Why is this change required? 2. What problem does it solve? 3. What scenario does it contribute to? 4. If it fixes an open issue, please link to the issue here. --> Fixes #4652 and reenabled integration tests for hugging face found we never added the prompt execution settings class into the right place in the HF class, fixed now. ### Description <!-- Describe your changes, the overall approach, the underlying design. These notes will help understanding how your code works. Thanks! --> ### Contribution Checklist <!-- Before submitting this PR, please make sure: --> - [x] The code builds clean without any errors or warnings - [x] The PR follows the [SK Contribution Guidelines](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md#development-scripts) raises no violations - [x] All unit tests pass, and I have added new tests where possible - [x] I didn't break anyone 😄
This commit is contained in:
@@ -26,7 +26,7 @@ jobs:
|
||||
run: |
|
||||
python -m pip install poetry pytest
|
||||
cd python
|
||||
poetry install --without chromadb --without hugging_face --without azure_cognitive_search --without weaviate --without pinecone --without postgres --without qdrant --without redis
|
||||
poetry install --without chromadb --without azure_cognitive_search --without weaviate --without pinecone --without postgres --without qdrant --without redis
|
||||
- name: Test with pytest
|
||||
run: |
|
||||
cd python && poetry run pytest ./tests/unit
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
[virtualenvs]
|
||||
in-project = true
|
||||
@@ -26,15 +26,10 @@ class HuggingFacePromptExecutionSettings(PromptExecutionSettings):
|
||||
|
||||
def prepare_settings_dict(self, **kwargs) -> Dict[str, Any]:
|
||||
gen_config = self.get_generation_config()
|
||||
if "prompt" in kwargs and kwargs["prompt"] is not None:
|
||||
return {
|
||||
"text_inputs": kwargs["prompt"],
|
||||
"generation_config": gen_config,
|
||||
"num_return_sequences": self.num_return_sequences,
|
||||
"do_sample": self.do_sample,
|
||||
}
|
||||
return {
|
||||
settings = {
|
||||
"generation_config": gen_config,
|
||||
"num_return_sequences": self.num_return_sequences,
|
||||
"do_sample": self.do_sample,
|
||||
}
|
||||
settings.update(kwargs)
|
||||
return settings
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
import logging
|
||||
from threading import Thread
|
||||
from typing import Any, AsyncIterable, Dict, List, Literal, Optional
|
||||
from typing import TYPE_CHECKING, Any, AsyncIterable, Dict, List, Literal, Optional
|
||||
|
||||
import torch
|
||||
import transformers
|
||||
from transformers import AutoTokenizer, TextIteratorStreamer, pipeline
|
||||
|
||||
from semantic_kernel.connectors.ai.ai_exception import AIException
|
||||
from semantic_kernel.connectors.ai.ai_service_client_base import AIServiceClientBase
|
||||
@@ -18,6 +18,9 @@ from semantic_kernel.connectors.ai.text_completion_client_base import (
|
||||
from semantic_kernel.models.contents.streaming_text_content import StreamingTextContent
|
||||
from semantic_kernel.models.contents.text_content import TextContent
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from semantic_kernel.connectors.ai.prompt_execution_settings import PromptExecutionSettings
|
||||
|
||||
logger: logging.Logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -31,7 +34,6 @@ class HuggingFaceTextCompletion(TextCompletionClientBase, AIServiceClientBase):
|
||||
ai_model_id: str,
|
||||
task: Optional[str] = "text2text-generation",
|
||||
device: Optional[int] = -1,
|
||||
log: Optional[Any] = None,
|
||||
model_kwargs: Optional[Dict[str, Any]] = None,
|
||||
pipeline_kwargs: Optional[Dict[str, Any]] = None,
|
||||
) -> None:
|
||||
@@ -59,20 +61,19 @@ class HuggingFaceTextCompletion(TextCompletionClientBase, AIServiceClientBase):
|
||||
|
||||
Note that this model will be downloaded from the Hugging Face model hub.
|
||||
"""
|
||||
generator = pipeline(
|
||||
task=task,
|
||||
model=ai_model_id,
|
||||
device=device,
|
||||
model_kwargs=model_kwargs,
|
||||
**pipeline_kwargs or {},
|
||||
)
|
||||
super().__init__(
|
||||
ai_model_id=ai_model_id,
|
||||
task=task,
|
||||
device=(f"cuda:{device}" if device >= 0 and torch.cuda.is_available() else "cpu"),
|
||||
generator=transformers.pipeline(
|
||||
task=task,
|
||||
model=ai_model_id,
|
||||
device=device,
|
||||
model_kwargs=model_kwargs,
|
||||
**pipeline_kwargs or {},
|
||||
),
|
||||
generator=generator,
|
||||
)
|
||||
if log:
|
||||
logger.warning("The `log` parameter is deprecated. Please use the `logging` module instead.")
|
||||
|
||||
async def complete(
|
||||
self,
|
||||
@@ -93,7 +94,7 @@ class HuggingFaceTextCompletion(TextCompletionClientBase, AIServiceClientBase):
|
||||
if kwargs.get("logger"):
|
||||
logger.warning("The `logger` parameter is deprecated. Please use the `logging` module instead.")
|
||||
try:
|
||||
results = self.generator(**settings.prepare_settings_dict(prompt=prompt))
|
||||
results = self.generator(prompt, **settings.prepare_settings_dict())
|
||||
except Exception as e:
|
||||
raise AIException("Hugging Face completion failed", e)
|
||||
if isinstance(results, list):
|
||||
@@ -133,18 +134,11 @@ class HuggingFaceTextCompletion(TextCompletionClientBase, AIServiceClientBase):
|
||||
If you need multiple responses, please use the complete method.",
|
||||
)
|
||||
try:
|
||||
tokenizer = transformers.AutoTokenizer.from_pretrained(self.ai_model_id)
|
||||
streamer = transformers.TextIteratorStreamer(tokenizer)
|
||||
args = {prompt}
|
||||
kwargs = {
|
||||
"num_return_sequences": settings.num_return_sequences,
|
||||
"generation_config": settings.get_generation_config(),
|
||||
"streamer": streamer,
|
||||
"do_sample": settings.do_sample,
|
||||
}
|
||||
|
||||
streamer = TextIteratorStreamer(AutoTokenizer.from_pretrained(self.ai_model_id))
|
||||
# See https://github.com/huggingface/transformers/blob/main/src/transformers/generation/streamers.py#L159
|
||||
thread = Thread(target=self.generator, args=args, kwargs=kwargs)
|
||||
thread = Thread(
|
||||
target=self.generator, args={prompt}, kwargs=settings.prepare_settings_dict(streamer=streamer)
|
||||
)
|
||||
thread.start()
|
||||
|
||||
for new_text in streamer:
|
||||
@@ -158,3 +152,7 @@ class HuggingFaceTextCompletion(TextCompletionClientBase, AIServiceClientBase):
|
||||
|
||||
except Exception as e:
|
||||
raise AIException("Hugging Face completion failed", e)
|
||||
|
||||
def get_prompt_execution_settings_class(self) -> "PromptExecutionSettings":
|
||||
"""Create a request settings object."""
|
||||
return HuggingFacePromptExecutionSettings
|
||||
|
||||
@@ -4,77 +4,10 @@ import sys
|
||||
|
||||
import pytest
|
||||
|
||||
import semantic_kernel.connectors.ai.hugging_face as sk_hf
|
||||
|
||||
if sys.version_info >= (3, 9):
|
||||
import semantic_kernel.connectors.ai.google_palm as sk_gp
|
||||
|
||||
|
||||
@pytest.fixture(
|
||||
scope="module",
|
||||
params=[
|
||||
("google/flan-t5-base", "text2text-generation"),
|
||||
("facebook/bart-large-cnn", "summarization"),
|
||||
],
|
||||
)
|
||||
def setup_hf_text_completion_function(create_kernel, request):
|
||||
kernel = create_kernel
|
||||
|
||||
# Configure LLM service
|
||||
kernel.add_text_completion_service(
|
||||
request.param[0],
|
||||
sk_hf.HuggingFaceTextCompletion(ai_model_id=request.param[0], task=request.param[1]),
|
||||
)
|
||||
|
||||
# Define semantic function using SK prompt template language
|
||||
sk_prompt = "Hello, I like {{$input}}{{$input2}}"
|
||||
|
||||
# Create the semantic function
|
||||
text2text_function = kernel.create_semantic_function(sk_prompt, max_tokens=25, temperature=0.7, top_p=0.5)
|
||||
|
||||
# User input
|
||||
simple_input = "sleeping and "
|
||||
|
||||
yield kernel, text2text_function, simple_input
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def setup_summarize_function(create_kernel):
|
||||
# User input (taken from https://en.wikipedia.org/wiki/Whale)
|
||||
text_to_summarize = """
|
||||
Whales are fully aquatic, open-ocean animals:
|
||||
they can feed, mate, give birth, suckle and raise their young at sea.
|
||||
Whales range in size from the 2.6 metres (8.5 ft) and 135 kilograms (298 lb)
|
||||
dwarf sperm whale to the 29.9 metres (98 ft) and 190 tonnes (210 short tons) blue whale,
|
||||
which is the largest known animal that has ever lived. The sperm whale is the largest
|
||||
toothed predator on Earth. Several whale species exhibit sexual dimorphism,
|
||||
in that the females are larger than males.
|
||||
"""
|
||||
additional_text = """
|
||||
The word "whale" comes from the Old English hwæl, from Proto-Germanic *hwalaz,
|
||||
from Proto-Indo-European *(s)kwal-o-, meaning "large sea fish".[3][4]
|
||||
The Proto-Germanic *hwalaz is also the source of Old Saxon hwal,
|
||||
Old Norse hvalr, hvalfiskr, Swedish val, Middle Dutch wal, walvisc, Dutch walvis,
|
||||
Old High German wal, and German Wal.[3] Other archaic English forms include wal,
|
||||
wale, whal, whalle, whaille, wheal, etc.[5]
|
||||
"""
|
||||
|
||||
# Define semantic function using SK prompt template language
|
||||
sk_prompt = "{{$input}} {{$input2}}"
|
||||
|
||||
kernel = create_kernel
|
||||
|
||||
# Configure LLM service
|
||||
kernel.add_text_completion_service(
|
||||
"facebook/bart-large-cnn",
|
||||
sk_hf.HuggingFaceTextCompletion(ai_model_id="facebook/bart-large-cnn", task="summarization"),
|
||||
)
|
||||
|
||||
# Create the semantic function
|
||||
summarize_function = kernel.create_semantic_function(sk_prompt, max_tokens=80, temperature=0, top_p=0.5)
|
||||
yield kernel, summarize_function, text_to_summarize, additional_text
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def setup_tldr_function_for_oai_models(create_kernel):
|
||||
kernel = create_kernel
|
||||
|
||||
@@ -1,147 +0,0 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import pytest
|
||||
from transformers import AutoTokenizer
|
||||
|
||||
import semantic_kernel as sk
|
||||
import semantic_kernel.connectors.ai.hugging_face as sk_hf
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.skip
|
||||
async def test_text2text_generation_input_str(setup_hf_text_completion_function):
|
||||
kernel, text2text_function, simple_input = setup_hf_text_completion_function
|
||||
|
||||
# Complete input string and print
|
||||
summary = await kernel.run(text2text_function, input_str=simple_input)
|
||||
|
||||
output = str(summary).strip()
|
||||
print(f"Completion using input string: '{output}'")
|
||||
assert len(output) > 0
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.skip
|
||||
async def test_text2text_generation_input_vars(setup_hf_text_completion_function):
|
||||
kernel, text2text_function, simple_input = setup_hf_text_completion_function
|
||||
|
||||
# Complete input as context variable and print
|
||||
context_vars = sk.ContextVariables(simple_input)
|
||||
summary = await kernel.run(text2text_function, input_vars=context_vars)
|
||||
|
||||
output = str(summary).strip()
|
||||
print(f"Completion using context variables: '{output}'")
|
||||
assert len(output) > 0
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.skip
|
||||
async def test_text2text_generation_input_context(setup_hf_text_completion_function):
|
||||
kernel, text2text_function, simple_input = setup_hf_text_completion_function
|
||||
|
||||
# Complete input context and print
|
||||
context = kernel.create_new_context()
|
||||
context["input"] = simple_input
|
||||
summary = await kernel.run(text2text_function, input_context=context)
|
||||
|
||||
output = str(summary).strip()
|
||||
print(f"Completion using input context: '{output}'")
|
||||
assert len(output) > 0
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.skip
|
||||
async def test_text2text_generation_input_context_with_vars(
|
||||
setup_hf_text_completion_function,
|
||||
):
|
||||
kernel, text2text_function, simple_input = setup_hf_text_completion_function
|
||||
|
||||
# Complete input context with additional variables and print
|
||||
context = kernel.create_new_context()
|
||||
context["input"] = simple_input
|
||||
context_vars = sk.ContextVariables("running and")
|
||||
summary = await kernel.run(text2text_function, input_context=context, input_vars=context_vars)
|
||||
|
||||
output = str(summary).strip()
|
||||
print(f"Completion using context and additional variables: '{output}'")
|
||||
assert len(output) > 0
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.skip
|
||||
async def test_text2text_generation_input_context_with_str(
|
||||
setup_hf_text_completion_function,
|
||||
):
|
||||
kernel, text2text_function, simple_input = setup_hf_text_completion_function
|
||||
|
||||
# Complete input context with additional input string and print
|
||||
context = kernel.create_new_context()
|
||||
context["input"] = simple_input
|
||||
summary = await kernel.run(text2text_function, input_context=context, input_str="running and")
|
||||
|
||||
output = str(summary).strip()
|
||||
print(f"Completion using context and additional string: '{output}'")
|
||||
assert len(output) > 0
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.skip
|
||||
async def test_text2text_generation_input_context_with_vars_and_str(
|
||||
setup_hf_text_completion_function,
|
||||
):
|
||||
kernel, text2text_function, simple_input = setup_hf_text_completion_function
|
||||
|
||||
# Complete input context with additional variables and string and print
|
||||
context = kernel.create_new_context()
|
||||
context["input"] = simple_input
|
||||
context_vars = sk.ContextVariables(variables={"input2": "running and"})
|
||||
summary = await kernel.run(
|
||||
text2text_function,
|
||||
input_context=context,
|
||||
input_vars=context_vars,
|
||||
input_str="new text",
|
||||
)
|
||||
|
||||
output = str(summary).strip()
|
||||
print(f"Completion using context, additional variables, and additional string: '{output}'")
|
||||
assert len(output) > 0
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.skip
|
||||
async def test_text_generation_with_kwargs():
|
||||
simple_input = "sleeping and "
|
||||
model_name = "google/flan-t5-base"
|
||||
|
||||
tokenizer = AutoTokenizer.from_pretrained(pretrained_model_name_or_path=model_name, trust_remote_code=True)
|
||||
|
||||
hf_model = sk_hf.HuggingFaceTextCompletion(
|
||||
model_name,
|
||||
task="text2text-generation",
|
||||
model_kwargs={"repetition_penalty": 0.2},
|
||||
pipeline_kwargs={"tokenizer": tokenizer, "trust_remote_code": True},
|
||||
)
|
||||
|
||||
kernel = sk.Kernel()
|
||||
|
||||
# Configure LLM service
|
||||
kernel.add_text_completion_service("hf-local", hf_model)
|
||||
|
||||
# Define semantic function using SK prompt template language
|
||||
sk_prompt = "Hello, I like {{$input}}{{$input2}}"
|
||||
text2text_function = kernel.create_semantic_function(sk_prompt, max_tokens=25, temperature=0.2, top_p=0.5)
|
||||
|
||||
# Complete input context with additional variables and string and print
|
||||
context = kernel.create_new_context()
|
||||
context["input"] = simple_input
|
||||
context_vars = sk.ContextVariables(variables={"input2": "running and"})
|
||||
summary = await kernel.run(
|
||||
text2text_function,
|
||||
input_context=context,
|
||||
input_vars=context_vars,
|
||||
input_str="new text",
|
||||
)
|
||||
|
||||
output = str(summary).strip()
|
||||
print(f"Completion using context, additional variables, and additional string: '{output}'")
|
||||
assert len(output) > 0
|
||||
@@ -1,129 +0,0 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import pytest
|
||||
|
||||
import semantic_kernel as sk
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.skip
|
||||
async def test_summarize_input_str(setup_summarize_function):
|
||||
(
|
||||
kernel,
|
||||
summarize_function,
|
||||
text_to_summarize,
|
||||
additional_text,
|
||||
) = setup_summarize_function
|
||||
|
||||
# Summarize input string and print
|
||||
summary = await kernel.run(summarize_function, input_str=text_to_summarize)
|
||||
|
||||
output = str(summary).strip()
|
||||
print(f"Summary using input string: '{output}'")
|
||||
assert len(output) > 0
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.skip
|
||||
async def test_summarize_input_vars(setup_summarize_function):
|
||||
(
|
||||
kernel,
|
||||
summarize_function,
|
||||
text_to_summarize,
|
||||
additional_text,
|
||||
) = setup_summarize_function
|
||||
|
||||
# Summarize input as context variable and print
|
||||
context_vars = sk.ContextVariables(text_to_summarize)
|
||||
summary = await kernel.run(summarize_function, input_vars=context_vars)
|
||||
|
||||
output = str(summary).strip()
|
||||
print(f"Summary using context variables: '{output}'")
|
||||
assert len(output) > 0
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.skip
|
||||
async def test_summarize_input_context(setup_summarize_function):
|
||||
(
|
||||
kernel,
|
||||
summarize_function,
|
||||
text_to_summarize,
|
||||
additional_text,
|
||||
) = setup_summarize_function
|
||||
|
||||
# Summarize input context and print
|
||||
context = kernel.create_new_context()
|
||||
context["input"] = text_to_summarize
|
||||
summary = await kernel.run(summarize_function, input_context=context)
|
||||
|
||||
output = str(summary).strip()
|
||||
print(f"Summary using input context: '{output}'")
|
||||
assert len(output) > 0
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.skip
|
||||
async def test_summarize_input_context_with_vars(setup_summarize_function):
|
||||
(
|
||||
kernel,
|
||||
summarize_function,
|
||||
text_to_summarize,
|
||||
additional_text,
|
||||
) = setup_summarize_function
|
||||
|
||||
# Summarize input context with additional variables and print
|
||||
context = kernel.create_new_context()
|
||||
context["input"] = text_to_summarize
|
||||
context_vars = sk.ContextVariables(additional_text)
|
||||
summary = await kernel.run(summarize_function, input_context=context, input_vars=context_vars)
|
||||
|
||||
output = str(summary).strip()
|
||||
print(f"Summary using context and additional variables: '{output}'")
|
||||
assert len(output) > 0
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.skip
|
||||
async def test_summarize_input_context_with_str(setup_summarize_function):
|
||||
(
|
||||
kernel,
|
||||
summarize_function,
|
||||
text_to_summarize,
|
||||
additional_text,
|
||||
) = setup_summarize_function
|
||||
|
||||
# Summarize input context with additional input string and print
|
||||
context = kernel.create_new_context()
|
||||
context["input"] = text_to_summarize
|
||||
summary = await kernel.run(summarize_function, input_context=context, input_str=additional_text)
|
||||
|
||||
output = str(summary).strip()
|
||||
print(f"Summary using context and additional string: '{output}'")
|
||||
assert len(output) > 0
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.skip
|
||||
async def test_summarize_input_context_with_vars_and_str(setup_summarize_function):
|
||||
(
|
||||
kernel,
|
||||
summarize_function,
|
||||
text_to_summarize,
|
||||
additional_text,
|
||||
) = setup_summarize_function
|
||||
|
||||
# Summarize input context with additional variables and string and print
|
||||
context = kernel.create_new_context()
|
||||
context["input"] = text_to_summarize
|
||||
context_vars = sk.ContextVariables(variables={"input2": additional_text})
|
||||
summary = await kernel.run(
|
||||
summarize_function,
|
||||
input_context=context,
|
||||
input_vars=context_vars,
|
||||
input_str="new text",
|
||||
)
|
||||
|
||||
output = str(summary).strip()
|
||||
print(f"Summary using context, additional variables, and additional string: '{output}'")
|
||||
assert len(output) > 0
|
||||
@@ -0,0 +1,105 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import pytest
|
||||
|
||||
import semantic_kernel.connectors.ai.hugging_face as sk_hf
|
||||
from semantic_kernel.kernel import Kernel
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize(
|
||||
("model_name", "task", "input_str"),
|
||||
[
|
||||
(
|
||||
"patrickvonplaten/t5-tiny-random",
|
||||
"text2text-generation",
|
||||
"translate English to Dutch: Hello, how are you?",
|
||||
),
|
||||
(
|
||||
"jotamunz/billsum_tiny_summarization",
|
||||
"summarization",
|
||||
"""
|
||||
Summarize: Whales are fully aquatic, open-ocean animals:
|
||||
they can feed, mate, give birth, suckle and raise their young at sea.
|
||||
Whales range in size from the 2.6 metres (8.5 ft) and 135 kilograms (298 lb)
|
||||
dwarf sperm whale to the 29.9 metres (98 ft) and 190 tonnes (210 short tons) blue whale,
|
||||
which is the largest known animal that has ever lived. The sperm whale is the largest
|
||||
toothed predator on Earth. Several whale species exhibit sexual dimorphism,
|
||||
in that the females are larger than males.
|
||||
""",
|
||||
),
|
||||
("HuggingFaceM4/tiny-random-LlamaForCausalLM", "text-generation", "Hello, I like sleeping and "),
|
||||
],
|
||||
ids=["text2text-generation", "summarization", "text-generation"],
|
||||
)
|
||||
async def test_text_completion(model_name, task, input_str):
|
||||
kernel = Kernel()
|
||||
|
||||
# Configure LLM service
|
||||
kernel.add_text_completion_service(
|
||||
service_id=model_name,
|
||||
service=sk_hf.HuggingFaceTextCompletion(ai_model_id=model_name, task=task),
|
||||
)
|
||||
|
||||
# Define semantic function using SK prompt template language
|
||||
sk_prompt = "{{$input}}"
|
||||
|
||||
# Create the semantic function
|
||||
function = kernel.create_semantic_function(sk_prompt, max_tokens=25, temperature=0.7, top_p=0.5)
|
||||
|
||||
summary = await kernel.run(function, input_str=input_str)
|
||||
|
||||
output = str(summary).strip()
|
||||
print(f"Completion using input string: '{output}'")
|
||||
assert len(output) > 0
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize(
|
||||
("model_name", "task", "input_str"),
|
||||
[
|
||||
(
|
||||
"patrickvonplaten/t5-tiny-random",
|
||||
"text2text-generation",
|
||||
"translate English to Dutch: Hello, how are you?",
|
||||
),
|
||||
(
|
||||
"jotamunz/billsum_tiny_summarization",
|
||||
"summarization",
|
||||
"""
|
||||
Summarize: Whales are fully aquatic, open-ocean animals:
|
||||
they can feed, mate, give birth, suckle and raise their young at sea.
|
||||
Whales range in size from the 2.6 metres (8.5 ft) and 135 kilograms (298 lb)
|
||||
dwarf sperm whale to the 29.9 metres (98 ft) and 190 tonnes (210 short tons) blue whale,
|
||||
which is the largest known animal that has ever lived. The sperm whale is the largest
|
||||
toothed predator on Earth. Several whale species exhibit sexual dimorphism,
|
||||
in that the females are larger than males.
|
||||
""",
|
||||
),
|
||||
# skipped for now, as it takes too long
|
||||
("HuggingFaceM4/tiny-random-LlamaForCausalLM", "text-generation", "Hello, I like sleeping and "),
|
||||
],
|
||||
ids=["text2text-generation", "summarization", "text-generation"],
|
||||
)
|
||||
async def test_text_completion_stream(model_name, task, input_str):
|
||||
kernel = Kernel()
|
||||
|
||||
# Configure LLM service
|
||||
kernel.add_text_completion_service(
|
||||
service_id=model_name,
|
||||
service=sk_hf.HuggingFaceTextCompletion(ai_model_id=model_name, task=task),
|
||||
)
|
||||
|
||||
# Define semantic function using SK prompt template language
|
||||
sk_prompt = "{{$input}}"
|
||||
|
||||
# Create the semantic function
|
||||
function = kernel.create_semantic_function(sk_prompt, max_tokens=25, temperature=0.7, top_p=0.5)
|
||||
|
||||
summary = ""
|
||||
async for text in kernel.run_stream(function, input_str=input_str):
|
||||
summary += str(text[0])
|
||||
|
||||
output = str(summary).strip()
|
||||
print(f"Completion using input string: '{output}'")
|
||||
assert len(output) > 0
|
||||
Reference in New Issue
Block a user