Notifier
The Notifier component provides a pluggable notification system for sending alerts during training. When exceptions occur or training events need attention, notifiers deliver messages to external channels (e.g., DingTalk webhooks).
Base Interface
from twinkle.notifier import Notifier
class Notifier:
def __call__(self, message: str):
"""Send a notification message."""
...
def to_dict(self) -> dict:
"""Serialize for checkpoint/restore."""
...
@classmethod
def from_dict(cls, data: dict) -> Notifier:
"""Restore from serialized form."""
...
DingNotifier
Sends notifications to DingTalk (钉钉) custom robot webhooks.
from twinkle.notifier import DingNotifier
notifier = DingNotifier(
ding_url='https://oapi.dingtalk.com/robot/send?access_token=xxx',
secret='SECxxxxxxx', # Optional: for signed robots
timeout=5.0,
)
# Send a message
notifier("### Training Complete\n\n- Steps: 1000\n- Loss: 0.25")
Parameters:
ding_url: Full DingTalk webhook URL with access tokensecret: Optional signing secret for signed-robot modetimeout: HTTP request timeout in seconds (default: 5.0)
Messages are sent as DingTalk Markdown format. The first heading line is extracted as the chat preview title.
Exception Notifications
Twinkle provides automatic exception notification with deduplication:
from twinkle.notifier.base import notify_exception
# Automatically sends formatted exception info
# Only one rank sends per unique exception (prevents flooding)
try:
model.forward_backward(batch)
except Exception as e:
notify_exception(notifier, context='forward_backward', exc=e, name='sft_train')
The notification includes:
Exception type and message
Full traceback
Runtime metadata (rank, PID, hostname)
Deduplication: only one notification per unique exception across all ranks
Custom Notifier
Create custom notifiers by subclassing Notifier:
from twinkle.notifier import Notifier
class SlackNotifier(Notifier):
def __init__(self, webhook_url: str):
self.webhook_url = webhook_url
def __call__(self, message: str):
import requests
requests.post(self.webhook_url, json={'text': message})
def to_dict(self):
return {'class': 'SlackNotifier', 'webhook_url': self.webhook_url}
@classmethod
def _from_dict_impl(cls, data):
return cls(webhook_url=data['webhook_url'])
Notifiers are registered automatically via
__init_subclass__, soNotifier.from_dict()can restore any subclass by name.