llmware-ai--llmware
201 行
8.6 KiB
Python
201 行
8.6 KiB
Python
|
|
""" Function Calling with SLIMs - this example illustrates how to move beyond basic question-answer prompting,
|
|
and begin to integrate function calls into LLM-based workflows.
|
|
|
|
Generally, function-calling is a specialized capability of frontier language models, such as OpenAI GPT4.
|
|
|
|
We have adapted this concept to small language models through SLIMs (Structured Language Instruction Models),
|
|
which are 'single function' models fine-tuned to accept three main inputs to construct a prompt:
|
|
|
|
As of June 2024, there are 18 distinct SLIM function calling models with many more on the way, for most common
|
|
extraction, classification, and summarization tasks.
|
|
|
|
All SLIM models have a common prompting structure
|
|
|
|
Inputs:
|
|
-- text passage - this is the core passage or piece of text that you would like the model to assess
|
|
-- function - classify, extract, generate - this is handled by default by the model class, so usually does
|
|
not need to be explicitly declared - but is an option for SLIMs that support more than one function
|
|
-- params - depends upon the model, used to configure/guide the behavior of the function call - optional for
|
|
some SLIMs
|
|
|
|
Outputs:
|
|
-- structured python output, generally either a dictionary or list
|
|
|
|
Main objectives:
|
|
-- enable function calling with small, locally-running models,
|
|
-- simplify prompts by defining specific functions and fine-tuning the model to respond accordingly
|
|
without 'prompt magic'
|
|
-- standardized outputs that can be handled programmatically as part of a multi-step workflow.
|
|
"""
|
|
|
|
|
|
from llmware.models import ModelCatalog
|
|
|
|
|
|
def discover_slim_models():
|
|
|
|
""" Discover a list of SLIM tools in the Model Catalog.
|
|
|
|
-- SLIMs are available in both traditional Pytorch and quantized GGUF packages.
|
|
-- Generally, we train/fine-tune in Pytorch and then package in 4-bit quantized GGUF for inference.
|
|
-- By default, we designate the GGUF versions with 'tool' or 'gguf' in their names.
|
|
-- GGUF versions are generally faster to load, faster for inference and use less memory in most environments."""
|
|
|
|
tools = ModelCatalog().list_llm_tools()
|
|
tool_map = ModelCatalog().get_llm_fx_mapping()
|
|
|
|
print("\nList of SLIM model tools (GGUF) in the ModelCatalog\n")
|
|
|
|
for i, tool in enumerate(tools):
|
|
model_card = ModelCatalog().lookup_model_card(tool_map[tool])
|
|
print(f"{i} - tool: {tool} - "
|
|
f"model_name: {model_card['model_name']} - "
|
|
f"model_family: {model_card['model_family']}")
|
|
|
|
return 0
|
|
|
|
|
|
def hello_world_slim():
|
|
|
|
""" SLIM models can be identified in the ModelCatalog like any llmware model. Instead of using
|
|
inference method, SLIM models are used with the function_call method that prepares a special prompt
|
|
instruction, and takes optional parameters.
|
|
|
|
This example shows a series of function calls with different SLIM models.
|
|
|
|
Please note that the first time the models will be pulled from the llmware Huggingface repository, and will
|
|
take a couple of minutes. Future calls will be much faster once cached in memory locally. """
|
|
|
|
print("\nExecuting Function Call Inferences with SLIMs\n")
|
|
|
|
# Sentiment Analysis
|
|
|
|
passage1 = ("This is one of the best quarters we can remember for the industrial sector "
|
|
"with significant growth across the board in new order volume, as well as price "
|
|
"increases in excess of inflation. We continue to see very strong demand, especially "
|
|
"in Asia and Europe. Accordingly, we remain bullish on the tier 1 suppliers and would "
|
|
"be accumulating more stock on any dips.")
|
|
|
|
# here are the two key lines of code
|
|
model = ModelCatalog().load_model("slim-sentiment-tool")
|
|
response = model.function_call(passage1)
|
|
|
|
print("sentiment response: ", response['llm_response'])
|
|
|
|
# Named Entity Recognition
|
|
|
|
passage2 = "Michael Johnson was a famous Olympic sprinter from the U.S. in the early 2000s."
|
|
|
|
model = ModelCatalog().load_model("slim-ner-tool")
|
|
response = model.function_call(passage2)
|
|
|
|
print("ner response: ", response['llm_response'])
|
|
|
|
# Extract anything with Slim-extract
|
|
|
|
passage3 = ("Adobe shares tumbled as much as 11% in extended trading Thursday after the design software maker "
|
|
"issued strong fiscal first-quarter results but came up slightly short on quarterly revenue guidance. "
|
|
"Here’s how the company did, compared with estimates from analysts polled by LSEG, formerly known as Refinitiv: "
|
|
"Earnings per share: $4.48 adjusted vs. $4.38 expected Revenue: $5.18 billion vs. $5.14 billion expected "
|
|
"Adobe’s revenue grew 11% year over year in the quarter, which ended March 1, according to a statement. "
|
|
"Net income decreased to $620 million, or $1.36 per share, from $1.25 billion, or $2.71 per share, "
|
|
"in the same quarter a year ago. During the quarter, Adobe abandoned its $20 billion acquisition of "
|
|
"design software startup Figma after U.K. regulators found competitive concerns. The company paid "
|
|
"Figma a $1 billion termination fee.")
|
|
|
|
model = ModelCatalog().load_model("slim-extract-tool")
|
|
response = model.function_call(passage3, function="extract", params=["revenue growth"])
|
|
|
|
print("extract response: ", response['llm_response'])
|
|
|
|
# Generate questions with Slim-Q-Gen
|
|
|
|
model = ModelCatalog().load_model("slim-q-gen-tiny-tool", temperature=0.2, sample=True)
|
|
# supported params - "question", "multiple choice", "boolean"
|
|
response = model.function_call(passage3, params=['multiple choice'])
|
|
|
|
print("question generation response: ", response['llm_response'])
|
|
|
|
# Generate topic
|
|
|
|
model = ModelCatalog().load_model("slim-topics-tool")
|
|
response = model.function_call(passage3)
|
|
|
|
print("topics response: ", response['llm_response'])
|
|
|
|
# Generate headline summary with slim-xsum
|
|
model = ModelCatalog().load_model("slim-xsum-tool", temperature=0.0, sample=False)
|
|
response = model.function_call(passage3)
|
|
|
|
print("xsum response: ", response['llm_response'])
|
|
|
|
# Generate boolean with optional '(explain)` in parameter
|
|
model = ModelCatalog().load_model("slim-boolean-tool")
|
|
response = model.function_call(passage3, params=["Did Adobe revenue increase? (explain)"])
|
|
|
|
print("boolean response: ", response['llm_response'])
|
|
|
|
# Generate tags
|
|
model = ModelCatalog().load_model("slim-tags-tool", temperature=0.0, sample=False)
|
|
response = model.function_call(passage3)
|
|
|
|
print("tags response: ", response['llm_response'])
|
|
|
|
return 0
|
|
|
|
|
|
def using_logits_and_integrating_into_process():
|
|
|
|
""" This example shows two key elements of function calling SLIM models -
|
|
|
|
1. Using Logit Information to indicate confidence levels, especially for classifications.
|
|
2. Using the structured dictionary generated for programmatic handling in a larger process.
|
|
|
|
"""
|
|
|
|
print("\nExample: using logits and integrating into process\n")
|
|
|
|
text_passage = ("On balance, this was an average result, with earnings in line with expectations and "
|
|
"no big surprises to either the positive or the negative.")
|
|
|
|
# two key lines (load_model + execute function_call) + additional logit_analysis step
|
|
sentiment_model = ModelCatalog().load_model("slim-sentiment-tool", get_logits=True)
|
|
response = sentiment_model.function_call(text_passage)
|
|
analysis = ModelCatalog().logit_analysis(response,sentiment_model.model_card, sentiment_model.hf_tokenizer_name)
|
|
|
|
print("sentiment response: ", response['llm_response'])
|
|
|
|
print("\nAnalyzing response")
|
|
for keys, values in analysis.items():
|
|
print(f"{keys} - {values}")
|
|
|
|
# two key attributes of the sentiment output dictionary
|
|
sentiment_value = response["llm_response"]["sentiment"]
|
|
confidence_level = analysis["confidence_score"]
|
|
|
|
# use the sentiment classification as a 'if...then' decision point in a process
|
|
if "positive" in sentiment_value:
|
|
print("sentiment is positive .... will take 'positive' analysis path ...", sentiment_value)
|
|
else:
|
|
print("sentiment is negative .... will take 'negative' analysis path ...", sentiment_value)
|
|
|
|
if "positive" in sentiment_value and confidence_level > 0.8:
|
|
print("sentiment is positive with high confidence ... ", sentiment_value, confidence_level)
|
|
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
# discovering slim models in the llmware catalog
|
|
discover_slim_models()
|
|
|
|
# running function call inferences
|
|
hello_world_slim()
|
|
|
|
# doing interesting stuff with the output
|
|
using_logits_and_integrating_into_process()
|
|
|
|
|