β¨οΈ CommandsΒΆ
Commands in P2PFL orchestrate actions and data exchange within the decentralized network. Leveraging the Command Pattern, P2PFL decouples command senders and receivers, enabling flexible communication and easy extension with new commands. The CommunicationProtocol
receives and routes incoming commands to their respective handlers.
Command TableΒΆ
Type |
Command Class |
Description |
---|---|---|
Message |
Initiates federated learning across the network. |
|
Terminates the federated learning process. |
||
Signals model initialization on a node. |
||
Orchestrates voting for training set selection. |
||
Informs neighbors of completed model aggregations. |
||
Signals aggregation completion and readiness for the next stage. |
||
Shares evaluation metrics. |
||
Confirms node liveness and detects failures. |
||
Weights |
Distributes initial model weights. |
|
Sends a partial model update (used during aggregation). |
||
Sends a complete, aggregated model. |
Sending CommandsΒΆ
Nodes send commands through their CommunicationProtocol
instance. The protocol provides methods for constructing and sending messages containing commands.
For message commands, use build_msg()
to create a message, providing the command name and any required arguments as strings:
# Example: Sending the StartLearningCommand
communication_protocol.build_msg(StartLearningCommand.get_name(), [str(rounds), str(epochs)])
# Example: Sending the MetricsCommand
metrics = {"accuracy": 0.95, "loss": 0.05}
flattened_metrics = [str(item) for pair in metrics.items() for item in pair]
communication_protocol.build_msg(MetricsCommand.get_name(), flattened_metrics)
For weights commands, use build_weights()
to create a message containing the serialized model weights, contributors, and the number of samples used in training:
# Example: Sending the PartialModelCommand
serialized_model = model.encode_parameters() # Encode the model parameters into bytes
communication_protocol.build_weights(PartialModelCommand.get_name(), round_number, serialized_model, contributors, num_samples)
The send()
and broadcast()
methods of the CommunicationProtocol
are then used to transmit the constructed messages to specific neighbors or the entire network, respectively. For example, to broadcast a message:
message = self._communication_protocol.build_msg(...) # Or build_weights(...)
self._communication_protocol.broadcast(message)
Receiving and Executing CommandsΒΆ
The CommunicationProtocol
manages incoming commands. Crucially, you register command handlers with the protocol using add_command()
:
# Example: Registering commands (typically done during Node initialization)
commands = [
StartLearningCommand(...),
MetricsCommand(...),
# ... other commands
]
communication_protocol.add_command(commands) # or add_command(single_command)
This creates an internal registry within the CommunicationProtocol
. When a message arrives, the protocol extracts the command name, retrieves the corresponding Command
instance from the registry, and executes it using:
command_instance.execute(source_node, round_number, **arguments)
The source_node
and round_number
provide context, while arguments
contain any command-specific data.