기본 제공 모드 사용¶
참고
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.
Application-wide mods: These mods apply to all functions within the
ClientApp
.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:
Application-wide mods (executed first, in the order they are provided)
Function-specific mods (executed after application-wide mods, in the order they are provided)
ClientApp (core function that handles the incoming
Message
and returns the outgoingMessage
)Function-specific mods (on the way back, in reverse order)
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:
example_mod_1
(before handling)example_mod_2
(before handling)example_mod_3
(before handling)example_mod_4
(before handling)train
(handling message)example_mod_4
(after handling)example_mod_3
(after handling)example_mod_2
(after handling)example_mod_1
(after handling)
The execution order for an incoming evaluate message is as follows:
example_mod_1
(before handling)example_mod_2
(before handling)evaluate
(handling message)example_mod_2
(after handling)example_mod_1
(after handling)
결론¶
이 가이드를 따라 mods를 효과적으로 사용하여 ``ClientApp``의 기능을 향상시키는 방법을 배웠습니다. mods 순서는 매우 중요하며 입력과 출력이 처리되는 방식에 영향을 미친다는 점을 기억하세요.
Mods를 통해 더욱 강력하고 유연한 ``ClientApp``을 구축해 보세요!