Nodes/ComfyUI_AIIA/🎭 AIIA Emotion Annotator (LLM)
ComfyUI Node

🎭 AIIA Emotion Annotator (LLM)

Let an LLM Do the Chore

By havvk·Created about a year ago·Updated 6 months ago· 13
🎭 AIIA Emotion Annotator (LLM)
    • dialogue_json
    • annotation_log
    dialogue_json
    modelllama-3.1-8b-instant
    override_modeskip_existing
    api_base_urlhttps://api.groq.com/openai/v1
    api_key_override
    custom_model
    proxy_url

    Writing [Happy] in front of every line of a 40-line podcast script gets old fast. 🎭 AIIA Emotion Annotator (LLM) exists so you never have to - it reads the script and adds the emotion tags for you, using a plain OpenAI-compatible LLM API. It slots between your script parser and the TTS node, and if you don't connect it, nothing changes; the moment you do, your dialogue suddenly has per-line emotional color.

    How it works

    It takes dialogue_json (the structured script from AIIA Podcast Script Parser) and sends the numbered speech lines to an LLM with a list of 24 predefined emotion tags - happy, sad, angry, sarcastic, nervous, all the way to gossip - asking it to pick one per line. The response comes back as JSON, and the node writes each emotion into the line's emotion field. Lines tagged neutral get left alone (emotion: null), so the TTS reads them in a natural default voice instead of hamming it up.

    That's the whole trick, and it's genuinely non-invasive. Downstream:

    • CosyVoice consumes tags as [Happy] text inline.
    • Qwen3-TTS (CustomVoice/VoiceDesign) converts tags into its instruct commands, batching consecutive same-emotion lines so each batch has a single, clean instruction.
    • VibeVoice and Qwen Base strip the tags out so they don't get read aloud as words.

    The inputs that matter

    • model - defaults to llama-3.1-8b-instant, the fast/cheap Groq pick. Bigger options (llama-3.3-70b-versatile, qwen-qwq-32b, deepseek-r1-distill-llama-70b, gemma2-9b-it) are there if you want fancier reading comprehension; for tagging dialogue, the 8B is plenty.
    • override_mode - skip_existing keeps tags you already wrote by hand and only fills in the gaps (my default); overwrite_all lets the LLM redict everything.
    • api_base_url - defaults to https://api.groq.com/openai/v1, but this is a plain OpenAI-compatible call, so it works with Ollama (http://localhost:11434/v1), vLLM, or any local server. Set custom_model to name a model not in the dropdown (that's how you use a local one).
    • api_key_override - leave empty to use the GROQ_API_KEY environment variable. Yes, it's an API key - this is the one node in the pack that isn't fully local by default, though it's trivially local via Ollama.

    Outputs: dialogue_json (the annotated script) and annotation_log (what the LLM said, handy for debugging a weird tag).

    Install & caveats

    Standard pack install - havvk/ComfyUI_AIIA via ComfyUI Manager or a git clone into custom_nodes/, restart. No model downloads here; you need a working Groq key (or local LLM) instead. Worth knowing: the node deliberately skips ComfyUI's caching (IS_CHANGED returns the current time), so it re-queries the LLM on every run - that's correct behavior, not a bug, but it means every run costs a few API calls. And if you're pointing at a local Ollama, note it disables TLS verification for localhost hosts.

    CategoryAIIA/Podcast

    Inputs (7)

    NameTypeDefaultDescription
    dialogue_jsonSTRING
    modelCOMBOllama-3.1-8b-instant5 options: llama-3.1-8b-instant, llama-3.3-70b-versatile, qwen-qwq-32b, deepseek-r1-distill-llama-70b, gemma2-9b-it
    override_modeCOMBOskip_existing2 options: skip_existing, overwrite_all
    api_base_urloptSTRINGhttps://api.groq.com/openai/v1OpenAI-compatible API base URL. Examples: Groq: https://api.groq.com/openai/v1 Ollama: http://localhost:11434/v1 vLLM: http://localhost:8000/v1
    api_key_overrideoptSTRING可选。留空则使用环境变量 GROQ_API_KEY
    custom_modeloptSTRING自定义模型名(覆盖下拉选择),用于 Ollama/vLLM 本地模型
    proxy_urloptSTRINGHTTP/SOCKS5 代理。留空则使用环境变量 HTTPS_PROXY。 示例: http://127.0.0.1:8118 或 socks5://127.0.0.1:1080

    Outputs (2)

    NameTypeDescription
    dialogue_jsonSTRING
    annotation_logSTRING