This question was migrated from the Slack channel #questions.
Original Question:
Hi. How do i use the get_properties
method on the server side. I have sent some properties from the client to server in a dict format {"prop1": "lorem", "prop2": "ipsum"}
but I’m not sure how to retrieve/use it on the server side.
Answer:
Hi! You can use it in your strategy by calling the get_properties
function of the ClientProxy
objects. Here is a working example in a fork of a Flower contributor: flower/examples/quickstart-pytorch-slurm/strategy.py at 339e95daabd999355c3ce1dca8a5df9d937557d1 · jafermarq/flower · GitHub
Question:
Thanks for replying. In the example, get_properties
is used inside the configure_fit
or configure_eval
because it stops sending instructions to clients not participating in the training.My use case is somewhat different: I want to send some hardware properties of all the clients before any training starts. So, I’m not sure how to use get_properties
in my strategy since it does not really go inside configure_fit
or configure_eval
Answer:
But configure_fit
is called every time before the training starts. You could use it to call the get_properties
function of the clients without removing clients from the training.
Question:
I actually meant that I want the client properties just once and before the very first round of training
Answer:
Then you could do it in the initialize_parameters
function of your strategy, which is only called once before the start of the training
Question:
Thanks for sticking in this discussion. Let me tell you a bit more about my use case:
I want to send some CPU/GPU properties such as CPU family name, available VRAM in a dict format using get_properties
in client. As far as my knowledge, initialize_parameters
is used to ask any one client what are its global model params before starting training, In my case, I just want to communicate the hardware properties to the server from all the clients. Later on, I can use that information and ask the client with the most available VRAM (or the most powerful CPU) for its param using initialize_paramters
.
In summary, I don’t need model parameters. I only need some hardware info/properties.
Thanks for all the help
Answer:
Well the initialize_parameters
function has access to the ClientManager
, with it you can sample all of your clients, call their get_properties
functions, and then do what you need with the results. I might be wrong, but I think it should work as you need it to.
Maybe what I said wasn’t really clear, I meant that you could write a custom initialize_parameters
function that does what you want because this function is called before the training starts and has access to the ClientManager
Question:
initialize_parameters
is invoked even before the clients are connected. ccording to the docs “If no parameters are returned from initialize_parameters (i.e., None), the server will randomly select one client and ask it to provide its parameters”
Therefore I passed None in the initial_parameter in strategy declaration so that the func call directly goes to initialize_parameters .
This was my code:
def initialize_parameters(self, client_manager: ClientManager):
# Get a list of all connected clients
clients = client_manager.all()
# Create an instance of GetPropertiesIns
ins = GetPropertiesIns({})
# Call get_properties on each client and store the results
client_properties = {}
for cid, client in clients.items():
properties = client.get_properties(ins, timeout=30)
client_properties[cid] = properties.properties
print(f"CLIENT PROPS: {client_properties}")
initial_parameters = self.set_initial_parameters() # this is a helper func to load checkpoints
return initial_parameters
Answer:
You can use the wait_for
function of the ClientManager
in order to make sure that all clients are connected before you call get_properties
: flower/src/py/flwr/server/client_manager.py at 88f8e434489e7b99030664429d88bf66e0ecae66 · adap/flower · GitHub
Question:
Thanks. This is what I was looking for. I can now send client info to server before the any training starts. Thanks for the help
Solution:
Client side:
def get_properties(self, config : Config) -> Dict[str, Scalar]:
properties = {"value1": "lorem", "value2": "ipsum"}
return properties
Server side:
def initialize_parameters(self, client_manager: ClientManager):
client_manager.wait_for(num_clients = 2)
client_properties = {}
for cid, client in client_manager.all().items():
ins = GetPropertiesIns({})
client_properties[cid] = client.get_properties(ins, timeout = 30)
print(self._filter(client_properties)) # helper filter function
initial_parameters = self._set_initial_parameters() # for loading saved model checkpoints
return initial_parameters