Repository: facebookresearch/ParlAI

Issue:
RuntimeError on BB2 during interactivce_web mode with blended_skill_talk task
**Bug description**
RuntimeError: There must be exactly two agents for this world. 
Getting 'RuntimeError' error when trying to run **interactive_web** with BB2 and --task blended_skill_talk


**Reproduction steps**
``` 
python -m parlai.scripts.interactive_web --host 0.0.0.0 --task blended_skill_talk --model-file zoo:blenderbot2/blenderbot2_400M/model --search_server 'http://36.135.119.125:1111' 
```


**Logs**
```
4:14:22 WARN | Overriding opt["task"] to blended_skill_talk (previously: None)
14:14:22 WARN | Overriding opt["model_file"] to /home/sam/ParlAI/data/models/blenderbot2/blenderbot2_400M/model (previously: /checkpoint/kshust
er/projects/knowledge_bot/kbot_memfix_sweep25_Fri_Jul__9/338/model.oss)
14:14:22 WARN | Overriding opt["search_server"] to http://36.135.119.125:1111 (previously: None)
14:14:22 INFO | loading dictionary from /home/sam/ParlAI/data/models/blenderbot2/blenderbot2_400M/model.dict
14:14:22 INFO | num words = 50264
14:14:22 INFO | BlenderBot2Fid: full interactive mode on.
14:14:34 INFO | Creating the search engine retriever.
Some weights of the model checkpoint at bert-base-uncased were not used when initializing BertModel: ['cls.predictions.transform.dense.weight', `
 'cls.seq_relationship.bias', 'cls.seq_relationship.weight', 'cls.predictions.bias', 'cls.predictions.decoder.weight', 'cls.predictions.transfo
rm.LayerNorm.bias', 'cls.predictions.transform.dense.bias', 'cls.predictions.transform.LayerNorm.weight']
- This IS expected if you are initializing BertModel from the checkpoint of a model trained on another task or with another architecture (e.g. 
initializing a BertForSequenceClassification model from a BertForPreTraining model).
- This IS NOT expected if you are initializing BertModel from the checkpoint of a model that you expect to be exactly identical (initializing a
 BertForSequenceClassification model from a BertForSequenceClassification model).
14:14:44 INFO | Building Query Generator from file: /home/sam/ParlAI/data/models/blenderbot2/query_generator/model
14:14:50 INFO | Building Memory Decoder from file: /home/sam/ParlAI/data/models/blenderbot2/memory_decoder/model
14:14:57 INFO | Total parameters: 732,961,280 (731,781,632 trainable)
14:14:57 INFO | Loading existing model params from /home/sam/ParlAI/data/models/blenderbot2/blenderbot2_400M/model
14:14:58 INFO | Opt:
14:14:58 INFO |     activation: gelu
14:14:58 INFO |     adafactor_eps: '[1e-30, 0.001]'
14:14:58 INFO |     adam_eps: 1e-08
14:14:58 INFO |     add_p1_after_newln: False
14:14:58 INFO |     allow_missing_init_opts: False
14:14:58 INFO |     attention_dropout: 0.1
14:14:58 INFO |     batchsize: 12
14:14:58 INFO |     beam_block_full_context: False
14:14:58 INFO |     beam_block_list_filename: None
14:14:58 INFO |     beam_block_ngram: 3
14:14:58 INFO |     beam_context_block_ngram: 3
14:14:58 INFO |     beam_delay: 30
14:14:58 INFO |     beam_length_penalty: 0.65
14:14:58 INFO |     beam_min_length: 20
14:14:58 INFO |     beam_size: 10
14:14:58 INFO |     betas: '[0.9, 0.999]'
14:14:58 INFO |     bpe_add_prefix_space: None
14:14:58 INFO |     bpe_debug: False
14:14:58 INFO |     bpe_dropout: None
14:14:58 INFO |     bpe_merge: None
14:14:58 INFO |     bpe_vocab: None
14:14:58 INFO |     candidates: inline
14:14:58 INFO |     cap_num_predictions: 100
14:14:58 INFO |     checkpoint_activations: False
14:14:58 INFO |     codes_attention_num_heads: 4
14:14:58 INFO |     codes_attention_type: basic
14:14:58 INFO |     compressed_indexer_factory: IVF4096_HNSW128,PQ128
14:14:58 INFO |     compressed_indexer_gpu_train: False
14:14:58 INFO |     compressed_indexer_nprobe: 64
14:14:58 INFO |     compute_tokenized_bleu: False
14:14:58 INFO |     converting: False
14:14:58 INFO |     data_parallel: False
14:14:58 INFO |     datapath: /home/sam/ParlAI/data
14:14:58 INFO |     datatype: train:stream
14:14:58 INFO |     delimiter: '\n'
14:14:58 INFO |     dict_class: parlai.core.dict:DictionaryAgent
14:14:58 INFO |     dict_endtoken: __end__
14:14:58 INFO |     dict_file: /home/sam/ParlAI/data/models/blenderbot2/blenderbot2_400M/model.dict
14:14:58 INFO |     dict_initpath: None
14:14:58 INFO |     dict_language: english
14:14:58 INFO |     dict_loaded: True
14:14:58 INFO |     dict_lower: False
14:14:58 INFO |     dict_max_ngram_size: -1
14:14:58 INFO |     dict_maxtokens: -1
14:14:58 INFO |     dict_minfreq: 0
14:14:58 INFO |     dict_nulltoken: __null__
14:14:58 INFO |     dict_starttoken: __start__
14:14:58 INFO |     dict_textfields: text,labels
14:14:58 INFO |     embedding_projection: random
14:14:58 INFO |     embedding_size: 1024
14:14:58 INFO |     embedding_type: random
14:14:58 INFO |     embeddings_scale: True
14:14:58 INFO |     encode_candidate_vecs: True
14:14:58 INFO |     encode_candidate_vecs_batchsize: 256
14:14:58 INFO |     eval_candidates: inline
14:14:58 INFO |     ffn_size: 4096
14:14:58 INFO |     fixed_candidate_vecs: reuse
14:14:58 INFO |     fixed_candidates_path: None
14:14:58 INFO |     force_fp16_tokens: True
14:14:58 INFO |     fp16: False
14:14:58 INFO |     fp16_impl: safe
14:14:58 INFO |     generation_model: bart
14:14:58 INFO |     gold_document_key: __selected-docs__
14:14:58 INFO |     gold_document_titles_key: select-docs-titles
14:14:58 INFO |     gold_knowledge_passage_key: checked_sentence
14:14:58 INFO |     gold_knowledge_title_key: title
14:14:58 INFO |     gold_sentence_key: __selected-sentences__
14:14:58 INFO |     gpu: -1
14:14:58 INFO |     gradient_clip: 0.1
14:14:58 INFO |     hide_labels: False
14:14:58 INFO |     history_add_global_end_token: None
14:14:58 INFO |     history_reversed: False
14:14:58 INFO |     history_size: -1
14:14:58 INFO |     hnsw_ef_construction: 200
14:14:58 INFO |     hnsw_ef_search: 128
14:14:58 INFO |     hnsw_indexer_store_n: 128
14:14:58 INFO |     host: 0.0.0.0
14:14:58 INFO |     ignore_bad_candidates: False
14:14:58 INFO |     image_cropsize: 224
14:14:58 INFO |     image_mode: raw
14:14:58 INFO |     image_size: 256
14:14:58 INFO |     include_initial_utterances: False
14:14:58 INFO |     include_personas: True
14:14:58 INFO |     memory_decoder_delimiter: '\n'
14:14:58 INFO |     memory_decoder_ignore_phrase: persona:
14:14:58 INFO |     memory_decoder_key: full_text
14:14:58 INFO |     memory_decoder_model_file: zoo:blenderbot2/memory_decoder/model
14:14:58 INFO |     memory_decoder_one_line_memories: False
14:14:58 INFO |     memory_decoder_truncate: -1
14:14:58 INFO |     memory_doc_delimiter: :
14:14:58 INFO |     memory_doc_title_delimiter: ' / '
14:14:58 INFO |     memory_extractor_phrase: persona:
14:14:58 INFO |     memory_key: personas
14:14:58 INFO |     memory_reader_model: None
14:14:58 INFO |     memory_retriever_truncate: -1
14:14:58 INFO |     memory_writer_model: bert
14:14:58 INFO |     memory_writer_model_file: zoo:hallucination/multiset_dpr/hf_bert_base.cp
14:14:58 INFO |     min_doc_token_length: 64
14:14:58 INFO |     model: projects.blenderbot2.agents.blenderbot2:BlenderBot2FidAgent
14:14:58 INFO |     model_file: /home/sam/ParlAI/data/models/blenderbot2/blenderbot2_400M/model
14:14:58 INFO |     model_parallel: True
14:14:58 INFO |     momentum: 0
14:14:58 INFO |     multitask_weights: '[3.0, 1.0, 1.0, 1.0, 3.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]'
14:14:58 INFO |     mutators: None
14:14:58 INFO |     n_decoder_layers: 12
14:14:58 INFO |     n_docs: 5
14:14:58 INFO |     n_encoder_layers: 12
14:14:58 INFO |     n_extra_positions: 0
14:14:58 INFO |     n_heads: 16
14:14:58 INFO |     n_layers: 12
14:14:58 INFO |     n_positions: 1024
14:14:58 INFO |     n_ranked_doc_chunks: 1
14:14:58 INFO |     n_segments: 0
14:14:58 INFO |     nesterov: True
14:14:58 INFO |     no_cuda: False
14:14:58 INFO |     normalize_sent_emb: False
14:14:58 INFO |     nus: [0.7]
14:14:58 INFO |     optimizer: adamax
14:14:58 INFO |     outfile: 
14:14:58 INFO |     output_scaling: 1.0
14:14:58 INFO |     override: "{'host': '0.0.0.0', 'task': 'blended_skill_talk', 'model_file': '/home/sam/ParlAI/data/models/blenderbot2/blende
rbot2_400M/model', 'search_server': 'http://36.135.119.125:1111'}"
14:14:58 INFO |     parlai_home: /private/home/kshuster/ParlAI
14:14:58 INFO |     path_to_dense_embeddings: None
14:14:58 INFO |     path_to_dpr_passages: zoo:hallucination/wiki_passages/psgs_w100.tsv
14:14:58 INFO |     path_to_index: zoo:hallucination/wiki_index_compressed/compressed_pq
14:14:58 INFO |     person_tokens: False
14:14:58 INFO |     poly_attention_num_heads: 4
14:14:58 INFO |     poly_attention_type: basic
14:14:58 INFO |     poly_faiss_model_file: None
14:14:58 INFO |     poly_n_codes: 64
14:14:58 INFO |     poly_score_initial_lambda: 0.5
14:14:58 INFO |     polyencoder_init_model: wikito
14:14:58 INFO |     polyencoder_type: codes
14:14:58 INFO |     port: 8080
14:14:58 INFO |     print_docs: False
14:14:58 INFO |     query_generator_beam_min_length: 2
14:14:58 INFO |     query_generator_beam_size: 1
14:14:58 INFO |     query_generator_delimiter: '\n'
14:14:58 INFO |     query_generator_ignore_phrase: persona:
14:14:58 INFO |     query_generator_inference: beam
14:14:58 INFO |     query_generator_key: full_text
14:14:58 INFO |     query_generator_model_file: zoo:blenderbot2/query_generator/model
14:14:58 INFO |     query_generator_truncate: -1
14:14:58 INFO |     query_model: bert_from_parlai_rag
14:14:58 INFO |     rag_model_type: token
14:14:58 INFO |     rag_query_truncate: 512
14:14:58 INFO |     rag_retriever_query: full_history
14:14:58 INFO |     rag_retriever_type: search_engine
14:14:58 INFO |     rag_turn_discount_factor: 1.0
14:14:58 INFO |     rag_turn_marginalize: doc_then_turn
14:14:58 INFO |     retriever_delimiter: '\n'
14:14:58 INFO |     retriever_embedding_size: 768
14:14:58 INFO |     retriever_ignore_phrase: persona:
14:14:58 INFO |     return_cand_scores: False
14:14:58 INFO |     safe_personas_only: True
14:14:58 INFO |     save_format: conversations
14:14:58 INFO |     search_query_generator_beam_min_length: 2
14:14:58 INFO |     search_query_generator_beam_size: 1
14:14:58 INFO |     search_query_generator_inference: greedy
14:14:58 INFO |     search_query_generator_model_file: zoo:blenderbot2/query_generator/model
14:14:58 INFO |     search_query_generator_text_truncate: 512
14:14:58 INFO |     search_server: http://36.135.119.125:1111
14:14:58 INFO |     share_encoders: True
14:14:58 INFO |     share_search_and_memory_query_encoder: False
14:14:58 INFO |     share_word_embeddings: True
14:14:58 INFO |     single_turn: False
14:14:58 INFO |     skip_generation: False
14:14:58 INFO |     skip_retrieval_token: no_passages_used
14:14:58 INFO |     special_tok_lst: None
14:14:58 INFO |     split_lines: True
14:14:58 INFO |     splitted_chunk_length: 256
14:14:58 INFO |     starttime: Jul09_14-09
14:14:58 INFO |     t5_dropout: 0.0
14:14:58 INFO |     t5_generation_config: None
14:14:58 INFO |     t5_model_arch: t5-base
14:14:58 INFO |     t5_model_parallel: False
14:14:58 INFO |     task: blended_skill_talk
14:14:58 INFO |     temperature: 1.0
14:14:58 INFO |     text_truncate: 512
14:14:58 INFO |     tfidf_max_doc_paragraphs: -1
14:14:58 INFO |     tfidf_model_path: zoo:wikipedia_full/tfidf_retriever/model
14:14:58 INFO |     thorough: False
14:14:58 INFO |     topk: 10
14:14:58 INFO |     topp: 0.9
14:14:58 INFO |     train_predict: False
14:14:58 INFO | Current ParlAI commit: 33ce8b5b4cd40d93f22da097d5eb6ce475c56ca8
14:14:58 INFO | creating task(s): blended_skill_talk

Traceback (most recent call last):
  File "/opt/conda/lib/python3.7/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/opt/conda/lib/python3.7/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/home/sam/ParlAI/parlai/scripts/interactive_web.py", line 302, in <module>
    InteractiveWeb.main()
  File "/home/sam/ParlAI/parlai/core/script.py", line 129, in main
    return cls._run_args(None)
  File "/home/sam/ParlAI/parlai/core/script.py", line 101, in _run_args
    return cls._run_from_parser_and_opt(opt, parser)
  File "/home/sam/ParlAI/parlai/core/script.py", line 108, in _run_from_parser_and_opt
    return script.run()
  File "/home/sam/ParlAI/parlai/scripts/interactive_web.py", line 298, in run
    return interactive_web(self.opt)
  File "/home/sam/ParlAI/parlai/scripts/interactive_web.py", line 276, in interactive_web
    SHARED['world'] = create_task(SHARED.get('opt'), SHARED['agent'])
  File "/home/sam/ParlAI/parlai/core/worlds.py", line 1441, in create_task
    world = create_task_world(opt, user_agents, default_world=default_world)
  File "/home/sam/ParlAI/parlai/core/worlds.py", line 1414, in create_task_world
    return world_class(opt, task_agents + user_agents)
  File "/home/sam/ParlAI/parlai/tasks/blended_skill_talk/worlds.py", line 139, in __init__
    super().__init__(opt, agents, shared)
  File "/home/sam/ParlAI/parlai/tasks/interactive/worlds.py", line 34, in __init__
    super().__init__(opt, agents, shared)
  File "/home/sam/ParlAI/parlai/core/worlds.py", line 340, in __init__
    raise RuntimeError('There must be exactly two agents for this world.')
RuntimeError: There must be exactly two agents for this world. 
```

**Additional context**
Running with safe interactive mode is working fine
```
python -m parlai.scripts.safe_interactive --task blended_skill_talk --model-file zoo:blender
bot2/blenderbot2_400M/model --search_server 'http://36.135.119.125:1111' 
``` 



Discussion:

Resolving patch:
diff --git a/parlai/scripts/interactive_web.py b/parlai/scripts/interactive_web.py
--- a/parlai/scripts/interactive_web.py
+++ b/parlai/scripts/interactive_web.py
@@ -25,6 +25,8 @@
 import json
 import time
 
+from parlai.agents.local_human.local_human import LocalHumanAgent
+
 HOST_NAME = 'localhost'
 PORT = 8080
 
@@ -266,14 +268,14 @@ def wait():
 def interactive_web(opt):
     global SHARED
 
-    opt['task'] = 'parlai.agents.local_human.local_human:LocalHumanAgent'
+    human_agent = LocalHumanAgent(opt)
 
     # Create model and assign it to the specified task
     agent = create_agent(opt, requireModelExists=True)
     agent.opt.log()
     SHARED['opt'] = agent.opt
     SHARED['agent'] = agent
-    SHARED['world'] = create_task(SHARED.get('opt'), SHARED['agent'])
+    SHARED['world'] = create_task(SHARED.get('opt'), [human_agent, SHARED['agent']])
 
     MyHandler.protocol_version = 'HTTP/1.0'
     httpd = HTTPServer((opt['host'], opt['port']), MyHandler)


Test patch:
diff --git a/tests/test_interactive.py b/tests/test_interactive.py
--- a/tests/test_interactive.py
+++ b/tests/test_interactive.py
@@ -85,7 +85,7 @@ def _run_test_repeat(self, tmpdir: str, fake_input: FakeInput):
 
 
 class TestInteractiveWeb(unittest.TestCase):
-    def test_iweb(self):
+    def test_iweb(self, task: str = None):
         import threading
         import random
         import requests
@@ -93,10 +93,11 @@ def test_iweb(self):
         import parlai.scripts.interactive_web as iweb
 
         port = random.randint(30000, 40000)
+        kwargs = {'model': 'repeat_query', 'port': port}
+        if task:
+            kwargs['task'] = task
         thread = threading.Thread(
-            target=iweb.InteractiveWeb.main,
-            kwargs={'model': 'repeat_query', 'port': port},
-            daemon=True,
+            target=iweb.InteractiveWeb.main, kwargs=kwargs, daemon=True
         )
         thread.start()
         iweb.wait()
@@ -123,6 +124,9 @@ def test_iweb(self):
 
         iweb.shutdown()
 
+    def test_iweb_task(self):
+        self.test_iweb(task='convai2')
+
 
 class TestProfileInteractive(unittest.TestCase):
     def test_profile_interactive(self):