Probably Yes for torch jit scripts, and No for regular python functions.
I will describe my understanding of the framework in details. For c++ files, their root directory is (git master) torch/csrc/distributed.
Internally, torch rpc framework does the following things:


entry point: rpc.async, rpc.sync use the same _invoke_rpc() while rpc.remote use its own implementation. For these three methods, they all categorize your calls into three categories: builtin is for python builtin function, udf is for user defined functions, jit is for torch script. Then all three lower level calls go into the torch C library.


c library: the c-python interface is defined in rpc/init.cpp, which uses pybind11 to define the interfaces, on calling the interface, call guards (constructed before wrapped functions) are gil_scoped_release so GIL is released here for all three interface categories. The wrapped functions are defined in rpc/python_functions.cpp they will find your target rpc process (c++ class RpcAgent) and send your message to it. GIL will be reaquired after finishing the c function call due to the automatic deconstruction of call gaurds.


rpc agent: RpcAgent class will initialize cb_ member on construction, which is a unique_ptr of type RequestCallback, there are two derived classes of RpcAgent: TensorPipeAgent and ProcessGroupAgent. In the rpc use case you are dealing with ProcessGroupAgent, in its member function handleRecv() it will use the cb_member to handle the call back. All these agents are defined in rpc/<agent_name_lower_case>.cpp so you should be able to find them easily.


request callback: Request callback is an abstract functor defined in request_callback.h and request_callback.cpp, it has a virtual processMessage() method. Its real implementation in request_callback_impl.cpp defines this method and calls its member method processRpc().


process rpc: This function handles rpc calls based on its message type, SCRIPT_CALL and SCRIPT_REMOTE_CALL will handle jit scripted calls, however in PYTHON_CALL:
  {
       py::gil_scoped_acquire acquire;
       serializedPyObj =
       std::make_shared<SerializedPyObj>(pythonRpcHandler.serialize(
       pythonRpcHandler.runPythonUdf(std::move(upc).movePythonUdf())));
  }



There is a py::gil_scoped_acquire, according to the pybind11 definition, this will hold the gil lock until acquire is deconstructed (aka leaving this c++ scope), so Nope, you cannot leverage multicore by using multi-threads used in rpc.
Note this explanation is valid for commit hash 176174a68ba2d36b9a5aaef0943421682ecc66d4 and release till 1.5.0, as I can see in their source code that they are planning to further abstract away the switch case in processRpc() to an abstract execute() method of RpcCommandBase