tone / example.py
jptaylor's picture
Pipecat Tone rc1
ffee326
Raw History Blame Contribute Delete
2.92 kB
"""Tag the turns of a voice-agent call with Pipecat Tone.
pip install -r requirements.txt
python example.py # full precision: model.opt.onnx
python example.py --fp16 # the 16-bit file: model_fp16.onnx, half the size
The model files are read from this folder. Without them, as in a git checkout, they are downloaded once from Hugging
Face (pipecat-ai/tone, release rc1). With --fp16, only model_fp16.onnx, tokenizer.json and config.json are needed.
"""
import pathlib
import sys
HERE = pathlib.Path(__file__).resolve().parent
sys.path.insert(0, str(HERE / "runtime"))
from tonetext.runtime.classifier import ToneTextClassifier # noqa: E402
PRECISION = "fp16" if "--fp16" in sys.argv[1:] else "fp32"
MODEL_FILES = (["model_fp16.onnx", "tokenizer.json", "config.json"] if PRECISION == "fp16"
else ["model.opt.onnx", "model.onnx", "tokenizer.json", "config.json"])
model_dir = HERE
if not all((HERE / f).exists() for f in MODEL_FILES):
from huggingface_hub import snapshot_download
model_dir = snapshot_download("pipecat-ai/tone", revision="rc1", allow_patterns=MODEL_FILES)
tone = ToneTextClassifier(model_dir, threads=4, precision=PRECISION)
# A support call, the agent and the caller in turn. Each turn is read with the turn before it, as plain text: who said
# either is not needed.
CALL = [
"Thanks for calling Northwind Broadband, this is Ava. How can I help today?",
"hi um yeah my internet's been down since this morning",
"I'm sorry to hear that. Which plan are you on?",
"I think my husband set it up, I'm not sure",
"No problem. Can I take the account holder's date of birth?",
"Why do you need that?",
"It's only to confirm the account. The next engineer visit is in about forty minutes, I'm afraid.",
"Oh great, a forty minute wait. Love that.",
"Let me try a reset from my side first. The light on your router should turn green.",
"mm-hm",
"Do you know which router model you have?",
"No idea, sorry.",
"That's fine. Can you try loading a page now?",
"That's brilliant, it's working, thank you so much!",
"Is there anything else I can help with?",
"thanks, that's all i needed",
]
for previous, text in zip(CALL, CALL[1:]):
tags = tone.tag(text, previous)
sarcasm = f" 路 sarcastic ({tags.sarcasm.probability:.2f})" if tags.sarcasm.sarcastic else ""
backchannel = " 路 backchannel" if tags.backchannel.is_backchannel else ""
print(f"{text!r}")
print(f" emotion {tags.emotion.label} ({tags.emotion.intensity}) 路 move {tags.move.label} ({tags.move.confidence:.2f})"
f"{sarcasm}{backchannel}")
# The full output for one turn, as JSON
print(tone.tag("Oh great, a forty minute wait. Love that.",
previous="It's only to confirm the account. The next engineer visit is in about forty minutes, I'm afraid.")
.model_dump_json(indent=1))