Download example.py from pipecat-ai/tone: direct link, hf CLI and curl.
- Browser
- Download file 2.92 kB
-
https://huggingface.co/pipecat-ai/tone/resolve/main/example.py
- Command line
-
hf download hf://pipecat-ai/tone/example.py
-
curl -L -o example.py https://huggingface.co/pipecat-ai/tone/resolve/main/example.py
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)) | |