Networking

In Tutorial you learned how to use BigARTM locally on your machine, within single process. Now we are going to deploy BigARTM on several machines.

Network modus operandi

First think you do to distribute CPU-intensive processing onto several machines is to launch there a python_interface.NodeController component.

One simple way to do so is to use node_controller application, included in BigARTM distributive.

>node_controller.exe

Usage:
    ./node_controller <endpoint>

Example:
    ./node_controller tcp://*:5555

To connect to node_controller from master replace '*' with fully qualified DNS name of the host.

After NodeControler is launched, you may add its endpoint to MasterComponentConfig.node_connect_endpoint list and then use your python_interface.MasterComponent as usual. No further actions is required on the remote nodes.

Warning

Some requirements and limitations apply in network mode.

Proxy to MasterComponent

BigARTM also supports a special proxy mode, which allows you to perform experiments on a remote cluster. As before, you start by running node_controller executable on your target machines. Then you deploy MasterComponent in one of you target machines.

library = ArtmLibrary('artm.dll')

master_proxy_config = messages_pb2.MasterProxyConfig()
master_proxy_config.node_connect_endpoint = 'tcp://192.168.0.2:5555'

with library.CreateMasterComponent(master_proxy_config) as master_proxy:
  # Use master_proxy in the same way you usually use master component

Or, if you launched several nodes, you can utilize all of them by configuring your remote MasterComponent to work in Network modus operandi.

library = ArtmLibrary('artm.dll')

master_proxy_config = messages_pb2.MasterProxyConfig()
master_proxy_config.node_connect_endpoint = 'tcp://192.168.0.2:5555'
master_proxy_config.config.modus_operandi = MasterComponentConfig_ModusOperandi_Network
master_proxy_config.disk_path = '/fileshare'
master_proxy_config.node_connect_addpoint.append('tcp://192.168.0.3:5555');
master_proxy_config.node_connect_addpoint.append('tcp://192.168.0.4:5555');

with library.CreateMasterComponent(master_proxy_config) as master_proxy:
  # Use master_proxy in the same way you usually use master component

Combining network modus operandi with proxy

This python script assumes that you have started local node_controller process as follows:

set GLOG_logtostderr=1 & node_controller.exe tcp://*:5000 tcp://*:5556 tcp://*:5557

This python script will use ports as follows:

  • 5000 - port of the MasterComponent to communicate between MasterComponent and Proxy (this endpoint must be created by node_controller)
  • 5550 - port of the MasterComponent to communicate between MasterComponent and Nodes (this endpoint will be automatically created by the master component)
  • 5556, 5557 - ports of the NodeControllerComponent to communicate between MasterComponent and Nodes (this endpoint must be created by node_controller)
import artm.messages_pb2, artm.library, sys

# Network path of a shared folder with batches to process.
# The folder must be reachable from all remote node controllers.
target_folder = 'D:\\datasets\\nips'

# Dictionary file (must be located on developer's box that runs python script)
dictionary_file = 'D:\\datasets\\nips\\dictionary'

unique_tokens = artm.library.Library().LoadDictionary(dictionary_file)

# Create master component and infer topic model
proxy_config = artm.messages_pb2.MasterProxyConfig()
proxy_config.node_connect_endpoint = 'tcp://localhost:5000'
proxy_config.communication_timeout = 10000  # timeout (in ms) for communication between proxy and master component
proxy_config.polling_frequency  = 50  # polling frequency (in ms) for long-lasting operations, for example WaitIdle()
proxy_config.config.modus_operandi = artm.library.MasterComponentConfig_ModusOperandi_Network
proxy_config.config.communication_timeout = 2000  # timeout (in ms) for communication between master component and nodes
proxy_config.config.disk_path = target_folder
proxy_config.config.create_endpoint = 'tcp://*:5550'
proxy_config.config.connect_endpoint = 'tcp://localhost:5550'
proxy_config.config.node_connect_endpoint.append('tcp://localhost:5556')
proxy_config.config.node_connect_endpoint.append('tcp://localhost:5557')
proxy_config.config.processors_count = 1  # number of processors to create at every node

with artm.library.MasterComponent(config = proxy_config) as master:
  dictionary = master.CreateDictionary(unique_tokens)
  perplexity_score = master.CreatePerplexityScore()
  model = master.CreateModel(topics_count = 10, inner_iterations_count = 10)
  model.EnableScore(perplexity_score)
  model.Initialize(dictionary)

  for iter in range(0, 8):
        master.InvokeIteration(1)        # Invoke one scan of the entire collection...
        master.WaitIdle()                # and wait until it completes.
        model.Synchronize()              # Synchronize topic model.
        print "Iter#" + str(iter),
        print ": Perplexity = %.3f" % perplexity_score.GetValue(model).value