class_docstr: Stores a constituency model and its optimizer
  
  Not inheriting from common/trainer.py because there's no concept of change_lr (yet?)
class_docstr_tok: ["Stores","a","constituency","model","and","its","optimizer","Not","inheriting","from","common\/trainer.py","because","there","'s","no","concept","of","change_lr","(","yet","?",")"]
docstr: Build a new model just from the saved params and some extra args
  
  Refactoring allows other processors to include a constituency parser as a module
code: def model_from_params(params, args, foundation_cache=None):
      """
      Build a new model just from the saved params and some extra args
  
      Refactoring allows other processors to include a constituency parser as a module
      """
      saved_args = dict(params["config"])
      # some parameters which change the structure of a model have
      # to be ignored, or the model will not function when it is
      # reloaded from disk
      if args is None:
          args = {}
      update_args = copy.deepcopy(args)
      update_args.pop("bert_hidden_layers", None)
      update_args.pop("constituency_composition", None)
      update_args.pop("constituent_stack", None)
      update_args.pop("num_tree_lstm_layers", None)
      update_args.pop("transition_scheme", None)
      update_args.pop("transition_stack", None)
      update_args.pop("maxout_k", None)
      # if the pretrain or charlms are not specified, don't override the values in the model
      # (if any), since the model won't even work without loading the same charlm
      if (
          "wordvec_pretrain_file" in update_args
          and update_args["wordvec_pretrain_file"] is None
      ):
          update_args.pop("wordvec_pretrain_file")
      if (
          "charlm_forward_file" in update_args
          and update_args["charlm_forward_file"] is None
      ):
          update_args.pop("charlm_forward_file")
      if (
          "charlm_backward_file" in update_args
          and update_args["charlm_backward_file"] is None
      ):
          update_args.pop("charlm_backward_file")
      # we don't pop bert_finetune, with the theory being that if
      # the saved model has bert_finetune==True we can load the bert
      # weights but then not further finetune if bert_finetune==False
      saved_args.update(update_args)
  
      # TODO: not needed if we rebuild the models
      if saved_args.get("bert_finetune", None) is None:
          saved_args["bert_finetune"] = False
      if saved_args.get("stage1_bert_finetune", None) is None:
          saved_args["stage1_bert_finetune"] = False
  
      model_type = params["model_type"]
      if model_type == "LSTM":
          pt = Trainer.find_and_load_pretrain(
              saved_args, foundation_cache
          )
          if (
              saved_args["bert_finetune"]
              or saved_args["stage1_bert_finetune"]
              or any(
                  x.startswith("bert_model.")
                  for x in params["model"].keys()
              )
          ):
              # if bert_finetune is True, don't use the cached model!
              # otherwise, other uses of the cached model will be ruined
              bert_model, bert_tokenizer = load_bert(
                  saved_args.get("bert_model", None)
              )
              bert_saved = True
          else:
              bert_model, bert_tokenizer = load_bert(
                  saved_args.get("bert_model", None), foundation_cache
              )
              bert_saved = False
          forward_charlm = Trainer.find_and_load_charlm(
              saved_args["charlm_forward_file"],
              "forward",
              saved_args,
              foundation_cache,
          )
          backward_charlm = Trainer.find_and_load_charlm(
              saved_args["charlm_backward_file"],
              "backward",
              saved_args,
              foundation_cache,
          )
          model = LSTMModel(
              pretrain=pt,
              forward_charlm=forward_charlm,
              backward_charlm=backward_charlm,
              bert_model=bert_model,
              bert_tokenizer=bert_tokenizer,
              force_bert_saved=bert_saved,
              transitions=params["transitions"],
              constituents=params["constituents"],
              tags=params["tags"],
              words=params["words"],
              rare_words=params["rare_words"],
              root_labels=params["root_labels"],
              constituent_opens=params["constituent_opens"],
              unary_limit=params["unary_limit"],
              args=saved_args,
          )
      else:
          raise ValueError("Unknown model type {}".format(model_type))
      model.load_state_dict(params["model"], strict=False)
      # model will stay on CPU if device==None
      # can be moved elsewhere later, of course
      model = model.to(args.get("device", None))
      return model
  
imports: from collections import Counter
  from collections import namedtuple
  import copy
  from enum import Enum
  import logging
  from operator import itemgetter
  import os
  import random
  import re
  import sys
  import torch
  from torch import nn
  from stanza.models.common import pretrain
  from stanza.models.common import utils
  from stanza.models.common.foundation_cache import load_bert, load_charlm, load_pretrain, FoundationCache
  from stanza.models.common.large_margin_loss import LargeMarginInSoftmaxLoss
  from stanza.models.constituency import parse_transitions
  from stanza.models.constituency import parse_tree
  from stanza.models.constituency import transition_sequence
  from stanza.models.constituency import tree_reader
  from stanza.models.constituency.base_model import SimpleModel, UNARY_LIMIT
  from stanza.models.constituency.in_order_oracle import InOrderOracle
  from stanza.models.constituency.lstm_model import LSTMModel, StackHistory
  from stanza.models.constituency.parse_transitions import TransitionScheme
  from stanza.models.constituency.parse_tree import Tree
  from stanza.models.constituency.utils import retag_tags, retag_trees, build_optimizer, build_scheduler
  from stanza.models.constituency.utils import DEFAULT_LEARNING_EPS, DEFAULT_LEARNING_RATES, DEFAULT_LEARNING_RHO, DEFAULT_WEIGHT_DECAY
  from stanza.server.parser_eval import EvaluateParser, ParseResult
  from stanza.utils.get_tqdm import get_tqdm
  from stanza.utils.training.common import find_wordvec_pretrain, choose_charlm, find_charlm_file
  from stanza.resources.default_packages import default_charlms, default_pretrains
label_desc: Use image node_id 5 for calling the Trainer obj's underlying member method code with example usage: obj.model_from_params(params, args, foundation_cache) and returns: model