기본 제공 모드 사용

참고

This tutorial covers preview features. The functionality and interfaces may change in future versions.

이 튜토리얼에서는 내장 모드를 활용하여 ``ClientApp``의 동작을 보강하는 방법을 배우겠습니다. Mods(Modifiers라고도 함)를 사용하면 ``ClientApp``에서 작업이 처리되기 전과 후에 작업을 수행할 수 있습니다.

Mods란 무엇인가요?

Mod는 ``ClientApp``을 감싸는 콜러블입니다. 들어오는 ``Message``와 그 결과로 나가는 ``Message``를 조작하거나 검사할 수 있습니다. ``Mod``의 시그니처는 다음과 같습니다:

ClientAppCallable = Callable[[Message, Context], Message]
Mod = Callable[[Message, Context, ClientAppCallable], Message]

일반적인 mod 함수는 다음과 같은 모습일 수 있습니다:

from flwr.client.typing import ClientAppCallable
from flwr.common import Context, Message


def example_mod(msg: Message, ctx: Context, call_next: ClientAppCallable) -> Message:
    # Do something with incoming Message (or Context)
    # before passing it to the next layer in the chain.
    # This could be another Mod or, if this is the last Mod, the ClientApp itself.
    msg = call_next(msg, ctx)
    # Do something with outgoing Message (or Context)
    # before returning
    return msg

Mods 사용

Mods can be registered in two ways: Application-wide mods and Function-specific mods.

  1. Application-wide mods: These mods apply to all functions within the ClientApp.

  2. Function-specific mods: These mods apply only to a specific function (e.g, the function decorated by @app.train())

1. Registering Application-wide Mods

To use application-wide mods in your ClientApp, follow these steps:

Import the required mods

import flwr as fl
from flwr.client.mod import example_mod_1, example_mod_2

Create the ClientApp with application-wide mods

ClientApp``을 생성하고 mods를 ``mods argument에 목록으로 전달합니다. mods를 제공하는 순서가 중요합니다:

app = fl.client.ClientApp(
    client_fn=client_fn,  # Not needed if using decorators
    mods=[
        example_mod_1,  # Application-wide Mod 1
        example_mod_2,  # Application-wide Mod 2
    ],
)

If you define functions to handle messages using decorators instead of client_fn, e.g., @app.train(), you do not need to pass the client_fn argument.

2. Registering Function-specific Mods

Instead of applying mods to the entire ClientApp, you can specify them for a particular function:

import flwr as fl
from flwr.client.mod import example_mod_3, example_mod_4

app = fl.client.ClientApp()


@app.train(mods=[example_mod_3, example_mod_4])
def train(msg, ctx):
    # Training logic here
    return reply_msg


@app.evaluate()
def evaluate(msg, ctx):
    # Evaluation logic here
    return reply_msg

In this case, example_mod_3 and example_mod_4 are only applied to the train function.

Order of Execution

When the ClientApp runs, the mods execute in the following order:

  1. Application-wide mods (executed first, in the order they are provided)

  2. Function-specific mods (executed after application-wide mods, in the order they are provided)

  3. ClientApp (core function that handles the incoming Message and returns the outgoing Message)

  4. Function-specific mods (on the way back, in reverse order)

  5. Application-wide mods (on the way back, in reverse order)

각 mod는 다음 mod로 전달하기 전에 들어오는 ``Message``를 검사하고 수정할 기회가 있으며, 스택 위로 반환하기 전에 나가는 ``Message``도 마찬가지로 검사하고 수정할 수 있습니다.

Example Execution Flow

Assuming the following registration:

app = fl.client.ClientApp(mods=[example_mod_1, example_mod_2])


@app.train(mods=[example_mod_3, example_mod_4])
def train(msg, ctx):
    return Message(fl.common.RecordDict(), reply_to=msg)


@app.evaluate()
def evaluate(msg, ctx):
    return Message(fl.common.RecordDict(), reply_to=msg)

The execution order for an incoming train message is as follows:

  1. example_mod_1 (before handling)

  2. example_mod_2 (before handling)

  3. example_mod_3 (before handling)

  4. example_mod_4 (before handling)

  5. train (handling message)

  6. example_mod_4 (after handling)

  7. example_mod_3 (after handling)

  8. example_mod_2 (after handling)

  9. example_mod_1 (after handling)

The execution order for an incoming evaluate message is as follows:

  1. example_mod_1 (before handling)

  2. example_mod_2 (before handling)

  3. evaluate (handling message)

  4. example_mod_2 (after handling)

  5. example_mod_1 (after handling)

결론

이 가이드를 따라 mods를 효과적으로 사용하여 ``ClientApp``의 기능을 향상시키는 방법을 배웠습니다. mods 순서는 매우 중요하며 입력과 출력이 처리되는 방식에 영향을 미친다는 점을 기억하세요.

Mods를 통해 더욱 강력하고 유연한 ``ClientApp``을 구축해 보세요!