""" configuration_ivme_conversate.py HuggingFace transformers-compatible config wrapper for Ivme-Conversate-v3. This allows the model to be loaded via AutoConfig/AutoModelForCausalLM (with trust_remote_code=True), which external tools like ArithMark's official benchmark runner expect. Deliberately holds only architecture fields (no training internals - data sources, hyperparameters, repo details) so this can be pushed publicly alongside the model weights without exposing anything private. """ from transformers import PretrainedConfig class IvmeConversateConfig(PretrainedConfig): model_type = "ivme_conversate" def __init__( self, vocab_size=16000, n_layers=16, d_model=320, n_heads=8, d_ffn=853, context_len=1024, rope_theta=10000.0, rmsnorm_eps=1e-5, qknorm_eps=1e-5, tie_embeddings=True, **kwargs, ): self.vocab_size = vocab_size self.n_layers = n_layers self.d_model = d_model self.n_heads = n_heads self.d_ffn = d_ffn self.context_len = context_len # lm_eval's HFLM (and other external tools) auto-detect a # model's max context length by looking for one of the standard # transformers config field names: n_positions, # max_position_embeddings, or n_ctx - NOT our own custom # 'context_len' name. Without this, lm_eval silently fell back # to some other default (confirmed via a real run: it fed a # 2048-token sequence to a model with a real 1024-token limit, # crashing inside RoPE with a tensor-shape mismatch rather than # failing with a clear "context too long" message). Exposing # this standard alias lets lm_eval - and anything else that # follows this convention - correctly discover and respect our # real context window. self.max_position_embeddings = context_len self.rope_theta = rope_theta self.rmsnorm_eps = rmsnorm_eps self.qknorm_eps = qknorm_eps self.tie_embeddings = tie_embeddings # This model has no KV-cache implementation (prepare_inputs_for_ # generation always returns the full sequence, recomputed each # step). Defaulting use_cache to False means external callers # (e.g. ArithMark's benchmark runner, or anyone using # AutoModelForCausalLM.generate() without knowing this model's # internals) get correct behavior without needing to pass # use_cache=False explicitly - generate() would otherwise try to # set up a DynamicCache and crash looking for standard config # fields (num_hidden_layers etc.) this config doesn't define. kwargs.setdefault("use_cache", False) # tie_word_embeddings may already be present in kwargs when # reloading a previously-saved config.json (which stores # whatever was passed to super().__init__() the first time) - # pop it out first so we don't pass it twice on reload. kwargs.pop("tie_word_embeddings", None) # transformers' generate()/AutoModelForCausalLM machinery looks # for this standard field name in several places super().__init__( tie_word_embeddings=tie_embeddings, **kwargs, )