Skip to main content

Customize, control, and enhance LLM generation with logits processors, featuring visualization capabilities to inspect and understand state transitions

Project description

PyPI version License: MIT

litelines

Customize, control, and enhance LLM generation with logits processors, featuring visualization capabilities to inspect and understand state transitions.

Installation

pip install litelines

Dependencies

The only dependency is outlines-core.

Supported Frameworks

  • transformers

Basic Usage

  • Download a model and its tokenizer:
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer

device = torch.device("cuda") # "cuda", "mps", or "cpu"

model_id = "Qwen/Qwen2.5-0.5B-Instruct"
model = AutoModelForCausalLM.from_pretrained(model_id).to(device)
tokenizer = AutoTokenizer.from_pretrained(model_id)
  • Prepare the inputs to the LLM:
user_input = "Are you sentient?"
messages = [{"role": "user", "content": user_input}]
inputs = tokenizer.apply_chat_template(
    messages, 
    add_generation_prompt=True, 
    return_tensors="pt", 
    return_dict=True
).to(model.device)
  • Define a logits processor through a Pydantic schema or a regular expression and visualize it:
from litelines.transformers import SchemaProcessor

processor = SchemaProcessor(response_format=r"Yes\.|No\.", tokenizer=tokenizer)
processor.show_graph()
  • Generate a structured response:
generated = model.generate(**inputs, logits_processor=[processor])
print(tokenizer.decode(generated[0][inputs['input_ids'].shape[-1]:-1]))
# No.
  • Visualize the selected path:
processor.show_graph()

100% Guaranteed Valid JSON answer

  • Define a pydantic schema describing the required JSON or provide the JSON schema as a string:
from typing import Literal
from pydantic import BaseModel, Field

class Sentiment(BaseModel):
    """Correctly inferred `Sentiment` with all the required parameters with correct types."""
    label: Literal["positive", "negative"] = Field(
        ..., description="Sentiment of the text"
    )

'''
Alternatively, provide the JSON schema as a sting:
Sentiment = """{'description': 'Correctly inferred `Sentiment` with all the required parameters with correct types.',
 'properties': {'label': {'description': 'Sentiment of the text',
   'enum': ['positive', 'negative'],
   'title': 'Label',
   'type': 'string'}},
 'required': ['label'],
 'title': 'Sentiment',
 'type': 'object'}"""
'''
  • Prepare the inputs to the LLM:
user_input = "What is the sentiment of the following text: Awesome!"
messages = [{"role": "user", "content": user_input}]
inputs = tokenizer.apply_chat_template(
    messages, add_generation_prompt=True, return_tensors="pt", return_dict=True
).to(model.device)
  • Define the processor and visualize it:
from litelines.transformers import SchemaProcessor

processor = SchemaProcessor(response_format=Sentiment, tokenizer=tokenizer)
processor.show_graph()
  • Generate a structured answer:
generated = model.generate(**inputs, logits_processor=[processor])
print(tokenizer.decode(generated[0][inputs['input_ids'].shape[-1]:-1]))
# {"label": "positive"}
  • Visualize the selected path:
processor.show_graph()

100% Guaranteed Valid Tool Calling answer

  • Define a pydantic schema describing the tool:
from typing import Literal
from pydantic import BaseModel, Field


class Sentiment(BaseModel):
    """Correctly inferred `Sentiment` with all the required parameters with correct types."""
    label: Literal["positive", "negative"] = Field(
        ..., description="Sentiment of the text"
    )
  • Prepare the inputs to the LLM:
from openai import pydantic_function_tool

user_input = "What is the sentiment of the following text: Awesome!"
messages = [{"role": "user", "content": user_input}]
inputs = tokenizer.apply_chat_template(
    messages, add_generation_prompt=True, tools=[pydantic_function_tool(Sentiment)], return_tensors="pt", return_dict=True
).to(model.device)
  • Define the processor, add the parameter include_tool_call=True and visualize it:
from litelines.transformers import SchemaProcessor

processor = SchemaProcessor(response_format=Sentiment, tokenizer=tokenizer, include_tool_call=True)
processor.show_graph()
  • Generate a structured response:
generated = model.generate(**inputs, logits_processor=[processor])
print(tokenizer.decode(generated[0][inputs['input_ids'].shape[-1]:]))
# <tool_call>
# {"name": "Sentiment", "arguments": {"label": "positive"}}
# </tool_call>
  • Visualize the selected path:
processor.show_graph()

Allow Preamble but still get 100% Guaranteed Valid JSON/Tool Calling answer

  • Define a pydantic schema describing the required JSON or provide the JSON schema as a string:
from typing import Literal
from pydantic import BaseModel, Field

class Sentiment(BaseModel):
    """Correctly inferred `Sentiment` with all the required parameters with correct types."""
    label: Literal["positive", "negative"] = Field(
        ..., description="Sentiment of the text"
    )
  • Prepare the inputs to the LLM:
user_input = "What is the sentiment of the following text: Awesome!"
messages = [{"role": "user", "content": user_input}]
inputs = tokenizer.apply_chat_template(
    messages, add_generation_prompt=True, return_tensors="pt", return_dict=True
).to(model.device)
  • Define the processor, add parameter allow_preamble=True and visualize it:
from litelines.transformers import SchemaProcessor

processor = SchemaProcessor(response_format=Sentiment, tokenizer=tokenizer, allow_preamble=True)
processor.show_graph()
  • Generate a structured response:
generated = model.generate(**inputs, logits_processor=[processor])
print(tokenizer.decode(generated[0][inputs['input_ids'].shape[-1]:]))
# The sentiment of the text "Awesome!" is positive.
# {"label": "positive"}
  • Visualize the selected path:
processor.show_graph()

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

litelines-0.1.3.tar.gz (19.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

litelines-0.1.3-py3-none-any.whl (19.3 kB view details)

Uploaded Python 3

File details

Details for the file litelines-0.1.3.tar.gz.

File metadata

  • Download URL: litelines-0.1.3.tar.gz
  • Upload date:
  • Size: 19.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.14

File hashes

Hashes for litelines-0.1.3.tar.gz
Algorithm Hash digest
SHA256 1837193ffd6c655528834ca326c4d3162422be0b8c22016d960570aaace29775
MD5 efacaebe4102944f04e865a1a2034e4b
BLAKE2b-256 390ded2eb12ff9d6555cfaab4ec33baaefa3afd82cd4e6d6e44c9d699edbd0f7

See more details on using hashes here.

File details

Details for the file litelines-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: litelines-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 19.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.14

File hashes

Hashes for litelines-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 7d26c4574b82d176a1bd360b87572b6679b727817d208e24d7854175c2a07d1e
MD5 299ef90e56abce94a3f52bd6fcb9d022
BLAKE2b-256 c36bc2560829b3086f51ba6a28fb13f7d0738c7adf33ca49ab8d401c83de782a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page