로깅 구성#

Flower 로거는 federated 학습 워크로드에서 발생하는 모든 핵심 이벤트를 추적합니다. 기본적으로 표준 메시지 형식에 따라 정보를 표시합니다:

DEFAULT_FORMATTER = logging.Formatter(
"%(levelname)s %(name)s %(asctime)s | %(filename)s:%(lineno)d | %(message)s"
)

로그 메시지 수준(예: INFO, DEBUG), 타임스탬프, 로깅이 발생한 줄, 로그 메시지 자체 등 관련 정보를 포함합니다. 이러한 방식으로 로거는 일반적으로 다음과 같은 정보를 터미널에 표시합니다:

...
INFO flwr 2023-07-15 15:32:30,935 | server.py:125 | fit progress: (3, 392.5575705766678, {'accuracy': 0.2898}, 13.781953627998519)
DEBUG flwr 2023-07-15 15:32:30,935 | server.py:173 | evaluate_round 3: strategy sampled 25 clients (out of 100)
DEBUG flwr 2023-07-15 15:32:31,388 | server.py:187 | evaluate_round 3 received 25 results and 0 failures
DEBUG flwr 2023-07-15 15:32:31,388 | server.py:222 | fit_round 4: strategy sampled 10 clients (out of 100)
DEBUG flwr 2023-07-15 15:32:32,429 | server.py:236 | fit_round 4 received 10 results and 0 failures
INFO flwr 2023-07-15 15:32:33,516 | server.py:125 | fit progress: (4, 370.3378576040268, {'accuracy': 0.3294}, 16.36216809399957)
DEBUG flwr 2023-07-15 15:32:33,516 | server.py:173 | evaluate_round 4: strategy sampled 25 clients (out of 100)
DEBUG flwr 2023-07-15 15:32:33,966 | server.py:187 | evaluate_round 4 received 25 results and 0 failures
DEBUG flwr 2023-07-15 15:32:33,966 | server.py:222 | fit_round 5: strategy sampled 10 clients (out of 100)
DEBUG flwr 2023-07-15 15:32:34,997 | server.py:236 | fit_round 5 received 10 results and 0 failures
INFO flwr 2023-07-15 15:32:36,118 | server.py:125 | fit progress: (5, 358.6936808824539, {'accuracy': 0.3467}, 18.964264554999318)
...

파일에 로그 저장#

기본적으로 Flower 로그는 Federated 학습 워크로드를 실행하는 터미널에 출력됩니다. 이는 gRPC 기반 페더레이션(즉,:code:fl.simulation.start_simulation`를 실행하는 경우)과 :code:`VirtualClientEngine`을 사용하는 경우(즉, :코드:`fl.simulation.start_simulation`을 실행하는 경우) 모두에 적용됩니다. 경우에 따라 이 로그를 디스크에 저장하고 싶을 수도 있습니다. 이 경우 `fl.common.logger.configure() 함수를 호출하여 저장할 수 있습니다. 예를 들어:

import flwr as fl

...

# in your main file and before launching your experiment
# add an identifier to your logger
# then specify the name of the file where the log should be outputted to
fl.common.logger.configure(identifier="myFlowerExperiment", filename="log.txt")

# then start your workload
fl.simulation.start_simulation(...) # or fl.server.start_server(...)

위와 같이 하면 Flower는 터미널에 표시되는 로그를 log.txt`에 기록합니다. 파일은 코드를 실행한 디렉터리와 동일한 디렉터리에 생성됩니다. 검사해보면 위의 로그도 기록되지만 앞에 :code:`identifier 접두사가 붙는 것을 확인할 수 있습니다:

...
myFlowerExperiment | INFO flwr 2023-07-15 15:32:30,935 | server.py:125 | fit progress: (3, 392.5575705766678, {'accuracy': 0.2898}, 13.781953627998519)
myFlowerExperiment | DEBUG flwr 2023-07-15 15:32:30,935 | server.py:173 | evaluate_round 3: strategy sampled 25 clients (out of 100)
myFlowerExperiment | DEBUG flwr 2023-07-15 15:32:31,388 | server.py:187 | evaluate_round 3 received 25 results and 0 failures
myFlowerExperiment | DEBUG flwr 2023-07-15 15:32:31,388 | server.py:222 | fit_round 4: strategy sampled 10 clients (out of 100)
myFlowerExperiment | DEBUG flwr 2023-07-15 15:32:32,429 | server.py:236 | fit_round 4 received 10 results and 0 failures
myFlowerExperiment | INFO flwr 2023-07-15 15:32:33,516 | server.py:125 | fit progress: (4, 370.3378576040268, {'accuracy': 0.3294}, 16.36216809399957)
myFlowerExperiment | DEBUG flwr 2023-07-15 15:32:33,516 | server.py:173 | evaluate_round 4: strategy sampled 25 clients (out of 100)
myFlowerExperiment | DEBUG flwr 2023-07-15 15:32:33,966 | server.py:187 | evaluate_round 4 received 25 results and 0 failures
myFlowerExperiment | DEBUG flwr 2023-07-15 15:32:33,966 | server.py:222 | fit_round 5: strategy sampled 10 clients (out of 100)
myFlowerExperiment | DEBUG flwr 2023-07-15 15:32:34,997 | server.py:236 | fit_round 5 received 10 results and 0 failures
myFlowerExperiment | INFO flwr 2023-07-15 15:32:36,118 | server.py:125 | fit progress: (5, 358.6936808824539, {'accuracy': 0.3467}, 18.964264554999318)
...

나만의 메시지 기록#

애플리케이션과 관련된 메시지를 더 추가하여 Flower 로거에 기본적으로 표시되는 정보를 확장할 수 있습니다. 다음과 같이 쉽게 추가할 수 있습니다.

# in the python file you want to add custom messages to the Flower log
from logging import INFO, DEBUG
from flwr.common.logger import log

# For example, let's say you want to add to the log some info about the training on your client for debugging purposes

class FlowerClient(fl.client.NumPyClient):
    def __init__(self, cid: int ...):
        self.cid = cid
        self.net = ...
        ...

    def fit(self, parameters, config):
        log(INFO, f"Printing a custom INFO message at the start of fit() :)")

        set_params(self.net, parameters)

        log(DEBUG, f"Client {self.cid} is doing fit() with config: {config}")

        ...

이렇게 하면 로거에 기본 메시지 외에 위에서 지정한 대로 클라이언트가 소개한 메시지가 표시됩니다.

...
INFO flwr 2023-07-15 16:18:21,726 | server.py:89 | Initializing global parameters
INFO flwr 2023-07-15 16:18:21,726 | server.py:276 | Requesting initial parameters from one random client
INFO flwr 2023-07-15 16:18:22,511 | server.py:280 | Received initial parameters from one random client
INFO flwr 2023-07-15 16:18:22,511 | server.py:91 | Evaluating initial parameters
INFO flwr 2023-07-15 16:18:25,200 | server.py:94 | initial parameters (loss, other metrics): 461.2934241294861, {'accuracy': 0.0998}
INFO flwr 2023-07-15 16:18:25,200 | server.py:104 | FL starting
DEBUG flwr 2023-07-15 16:18:25,200 | server.py:222 | fit_round 1: strategy sampled 10 clients (out of 100)
INFO flwr 2023-07-15 16:18:26,391 | main.py:64 | Printing a custom INFO message :)
DEBUG flwr 2023-07-15 16:18:26,391 | main.py:63 | Client 44 is doing fit() with config: {'epochs': 5, 'batch_size': 64}
INFO flwr 2023-07-15 16:18:26,391 | main.py:64 | Printing a custom INFO message :)
DEBUG flwr 2023-07-15 16:18:28,464 | main.py:63 | Client 99 is doing fit() with config: {'epochs': 5, 'batch_size': 64}
INFO flwr 2023-07-15 16:18:28,465 | main.py:64 | Printing a custom INFO message :)
DEBUG flwr 2023-07-15 16:18:28,519 | main.py:63 | Client 67 is doing fit() with config: {'epochs': 5, 'batch_size': 64}
INFO flwr 2023-07-15 16:18:28,519 | main.py:64 | Printing a custom INFO message :)
DEBUG flwr 2023-07-15 16:18:28,615 | main.py:63 | Client 11 is doing fit() with config: {'epochs': 5, 'batch_size': 64}
INFO flwr 2023-07-15 16:18:28,615 | main.py:64 | Printing a custom INFO message :)
DEBUG flwr 2023-07-15 16:18:28,617 | main.py:63 | Client 13 is doing fit() with config: {'epochs': 5, 'batch_size': 64}
...

원격 서비스에 로그인#

또한 fl.common.logger.configure 함수를 사용하면 네이티브 Python logging.handler.HTTPHandler`를 통해 로그를 푸시할 있는 호스트를 지정할 있습니다(:code:`POST`를 통해). 이는 모든 엔티티(예: 서버 클라이언트)에서 로그를 수집하는 것이 번거로울 있는 :code:`gRPC 기반 Federated 학습 워크로드에서 특히 유용한 기능입니다. Flower 시뮬레이션에서는 서버가 모든 로그를 자동으로 표시합니다. 로그를 다른 곳에 백업하거나 분석하려는 경우 :code:`HTTPHandler`를 지정할 수 있습니다.