AI4Finance Foundation logo

FinGPT

FinGPTvopen-source financial LLM familyCurrent
byAI4Finance FoundationAI4Finance Foundation(open source)
Released February 11, 2023
Context4.1K tokens
Training CutoffVaries by released checkpoint
CategoryLarge Language Model
Max Output2.0K tokens

About FinGPT

FinGPT is an open-source financial large language model project from AI4Finance Foundation. It focuses on finance-specific NLP, sentiment analysis, robo-advisor workflows, technical analysis, and model release workflows through GitHub and Hugging Face.

Capabilities

textfinance nlpsentiment analysiscoderesearch

Input Modalities

text

Output Modalities

text

Technical Details

API Identifier
AI4Finance-Foundation/FinGPT
Category
Large Language Model
Context Window
4,096 tokens
Max Output Tokens
2,048 tokens

Tags

financial-llmfinanceopen-sourcesentiment-analysisfingpt

Run this model yourself

Local and cloud setup for FinGPT, with exact configurations, sources and clear evidence limits.

Find a model for your hardware
Local hardwareDocumented setupSources checked Oct 16, 2026

Run FinGPT Falcon-7B multitask analysis on a research CPU desktop

Load the exact Falcon-7B base and FinGPT multitask LoRA as a full FP32 CPU model. A private serial service returns answers for four original synthetic sentiment, relation, headline and named-entity fixtures using the published Instruction/Input/Answer format. Eight threads, one sequence, 2,048 total tokens and a 128-token output cap. Actual answer quality, memory fit and speed remain unmeasured.

Hardware
Intel Core i5-12400 desktop, 8 inference threads, 64 GiB RAM
Runtime
Native Falcon7B plus FinGPT LoRA private CPU multitask research service Transformers4.57.6;PEFT0.17.1;torch2.6.0+cpu;accelerate1.10.1;tokenizers0.22.2;Python3.12 · CPU
Model format
PyTorch LoRA adapter with required safetensors base · Full base and LoRA CPUFP32; native base checkpoint declares BF16; no8bit loading · No quantization; reader full base+adapter CPUFP32
Workload
2,048 token context · 1 concurrent

Based on source documentation; this setup has not been executed by OpenTools. Memory: unknown. No compatible measurement available.

Read the complete setup guide

Before you start

  • Use an owned Intel i5-12400 Ubuntu 24.04 x86_64 desktop with 64 GiB RAM, 80 GiB free disk and eight CPU threads. These allocations are not measured requirements.
  • Read both exact MIT adapter and Apache-2.0 base terms; preserve notices. Public native base and adapter are independently pinned. No gate or terms acceptance is performed for the reader.
  • This is a source-documented low-stakes educational multitask experiment with fictional original inputs, not investment advice, a trading tool, a financial forecast or measured accuracy. Actual semantic assessment is separate from protocol completion.
  • Use the exact FinGPT Falcon multitask LoRA and native tiiuae/falcon-7b base. The adapter config names a legacy local base path; exact publisher notebook explicitly maps falcon to the TII base. Other seven README-linked adapters and broader supported scope remain open.

Exact model and requirements

Artifact:
FinGPT / AI4Finance Foundation (adapter); TII (required Falcon-7B base) / Exact FinGPT Falcon-7B multitask LoRA plus required native Falcon-7B base · checkpoint FinGPT/fingpt-mt_falcon-7b_lora
Publisher revision:
69f69de456efdbed5729e797cf8991524a30f977
Artifact digest:
sha256:5ff09b168e9de46a89437825fad845fc3de0641963adf1c8d6da3a2883fd58a9
Download size:
Unknown
Memory requirement (unknown):
Unknown — No full-process peak measured for full Falcon7B CPUFP32, LoRA, FP32cache and runtime/OS buffers.
System RAM / disk:
Unknown / Unknown
Placement:
single device. One CPU host, no tensor/pipeline sharding. Whole native base, LoRA and generation run on CPU; no GPU/disk offload.
KV cache:
FP32 native Falcon multi-query attention cache; exact process/cache peak unmeasured.
Workload:
2,048 token context; Unknown; Unknown; concurrency 1; batch 1; cache cold; repetitions Unknown.
Tokenizer:
Exact native Falcon PreTrainedTokenizerFast; no chat template or added vocabulary · ec89142b67d748a1865ea4451372db8313ada0d8;tokenizers0.22.2
Sampling / reasoning:
Native notebook uses greedy do_sampleFalse. This author uses num_beams1, max_new_tokens128, EOS/pad11 and no sampling; require EOS and fewer than128 generated tokens, then decode only new IDs. No native confidence/calibration or correctness score. Plain native Instruction:... / Input:... / Answer: prompt from exact publisher notebook. Four model-supported tasks share one fixed-fixture service. No financial recommendation, forecasting, chat/thinking template or execution. Full2048totalcontext comes from native basecard/tokenizer; input+128cap must fit. Single unpadded sequence uses existing EOS as pad without adding a random PAD embedding.
Runtime prerequisites:
Ubuntu24.04 x86_64; See prerequisites above.

Official artifact · License

The exact FinGPT adapter card explicitly declares MIT; the parent FinGPT repository includes actual MIT text. Required TII Falcon-7B base card explicitly grants Apache-2.0, whose full license is archived. Retain applicable MIT copyright/permission notices and Apache license/NOTICE/change notices and patent conditions. No financial correctness, endorsement, trading authorization or legal clearance is granted. Original synthetic fixtures contain no real customer or trading data.

  • Both required base shards total 14,434,402,976 bytes; adapter adds 4,729,725 bytes, total 14,439,132,701 published weight bytes. Individual digests are not a measured combined model or memory figure.
  • 64 GiB RAM, 80 GiB disk and eight threads/vCPUs are planning allocations, not measured minima or proven fit. CPU FP32 expansion, loading transients, cache and OS add overhead; native base GPU16GB guidance is not CPU fit evidence.

One-time setup and hardware

hardware
Unknown — Existing desktop purchase price and incremental hardware cost depend on the reader; unknown.
Existing desktop purchase price and incremental hardware cost depend on the reader; unknown. Tax: unknown.
setup
Unknown — Initial provisioning/build time and labor cost are unknown.
Initial provisioning/build time and labor cost are unknown. Tax: unknown.

Recurring costs

electricity
Unknown — Actual wall power, electricity rate and powered hours are unknown; no TDP-to-wall-power conversion.
Actual wall power, electricity rate and powered hours are unknown; no TDP-to-wall-power conversion. Tax: unknown.
storage
Unknown — Incremental cost of local disk capacity is unknown. The 80 GiB free-disk walkthrough allocation is an author choice, not a measured requirement.
Incremental cost of local disk capacity is unknown. The 80 GiB free-disk walkthrough allocation is an author choice, not a measured requirement. Tax: unknown.
egress
Unknown — Data transfer price, allowances and traffic volume are unknown.
Data transfer price, allowances and traffic volume are unknown. Tax: unknown.
administration
Unknown — Maintenance labor rate and hours are unknown.
Maintenance labor rate and hours are unknown. Tax: unknown.

Install the runtime

  1. 1. Prepare the native CPU environment

    Install pinned CPU Torch and compatible native Transformers/PEFT releases in a dedicated environment. The publisher notebook originally uses 4.32/0.5 and CUDA 8-bit examples; this source-qualified native CPU path uses 4.57.6/0.17.1 with full FP32 and no bitsandbytes or remote model code. Record resolved transitive/system versions and stop on pip check/import/load errors; nothing was installed by the author.

    Command
    set -e
    sudo apt-get update
    sudo apt-get install -y python3.12 python3.12-venv curl ca-certificates openssl
    mkdir -p "$HOME/fingpt-falcon/base" "$HOME/fingpt-falcon/adapter"
    cd "$HOME/fingpt-falcon"
    python3.12 -m venv .venv
    .venv/bin/python -m pip install 'https://download.pytorch.org/whl/cpu/torch-2.6.0%2Bcpu-cp312-cp312-linux_x86_64.whl#sha256=59e78aa0c690f70734e42670036d6b541930b8eabbaa18d94e090abf14cc4d91'
    .venv/bin/python -m pip install 'transformers==4.57.6' 'peft==0.17.1' 'accelerate==1.10.1' 'safetensors==0.5.3' 'tokenizers==0.22.2' 'huggingface-hub==0.36.0' 'numpy==2.2.3'
    .venv/bin/python -m pip check
    .venv/bin/python -m pip freeze > resolved-environment.txt

    Expected result: Exact direct packages resolve and pip check passes; CPU wheel hash is checked by pip. Save resolution and stop on errors. No GPU driver/compiler or quantizer is used.

Download the model

  1. 1. Download every required base and adapter asset

    Reader downloads only; the author fetched metadata/text, not weight bodies. Both base shards and the LoRA are mandatory. Stream-check exact byte lengths and SHA-256 before any model or PyTorch adapter load. Never replace the base with Falcon-Instruct or omit a shard.

    Command
    set -e
    cd "$HOME/fingpt-falcon"
    curl --fail --location 'https://huggingface.co/tiiuae/falcon-7b/resolve/ec89142b67d748a1865ea4451372db8313ada0d8/config.json' -o 'base/config.json'
    curl --fail --location 'https://huggingface.co/tiiuae/falcon-7b/resolve/ec89142b67d748a1865ea4451372db8313ada0d8/generation_config.json' -o 'base/generation_config.json'
    curl --fail --location 'https://huggingface.co/tiiuae/falcon-7b/resolve/ec89142b67d748a1865ea4451372db8313ada0d8/model.safetensors.index.json' -o 'base/model.safetensors.index.json'
    curl --fail --location 'https://huggingface.co/tiiuae/falcon-7b/resolve/ec89142b67d748a1865ea4451372db8313ada0d8/model-00001-of-00002.safetensors' -o 'base/model-00001-of-00002.safetensors'
    curl --fail --location 'https://huggingface.co/tiiuae/falcon-7b/resolve/ec89142b67d748a1865ea4451372db8313ada0d8/model-00002-of-00002.safetensors' -o 'base/model-00002-of-00002.safetensors'
    curl --fail --location 'https://huggingface.co/tiiuae/falcon-7b/resolve/ec89142b67d748a1865ea4451372db8313ada0d8/tokenizer.json' -o 'base/tokenizer.json'
    curl --fail --location 'https://huggingface.co/tiiuae/falcon-7b/resolve/ec89142b67d748a1865ea4451372db8313ada0d8/tokenizer_config.json' -o 'base/tokenizer_config.json'
    curl --fail --location 'https://huggingface.co/tiiuae/falcon-7b/resolve/ec89142b67d748a1865ea4451372db8313ada0d8/special_tokens_map.json' -o 'base/special_tokens_map.json'
    curl --fail --location 'https://huggingface.co/FinGPT/fingpt-mt_falcon-7b_lora/resolve/69f69de456efdbed5729e797cf8991524a30f977/adapter_config.json' -o 'adapter/adapter_config.json'
    curl --fail --location 'https://huggingface.co/FinGPT/fingpt-mt_falcon-7b_lora/resolve/69f69de456efdbed5729e797cf8991524a30f977/adapter_model.bin' -o 'adapter/adapter_model.bin'
    cat > asset-manifest.json <<'PYMANIFEST'
    {
      "base/config.json": {
        "bytes": 1048,
        "sha256": "ef0b96fb53bf7627eb115138bdfd36edb5661891816546f41ed91fb80f19ab31",
        "url": "https://huggingface.co/tiiuae/falcon-7b/resolve/ec89142b67d748a1865ea4451372db8313ada0d8/config.json",
        "revision": "ec89142b67d748a1865ea4451372db8313ada0d8"
      },
      "base/generation_config.json": {
        "bytes": 117,
        "sha256": "54e9b0cf5be679b3c9bdc430ad850a40961e27298530c48e7da9133c963569a9",
        "url": "https://huggingface.co/tiiuae/falcon-7b/resolve/ec89142b67d748a1865ea4451372db8313ada0d8/generation_config.json",
        "revision": "ec89142b67d748a1865ea4451372db8313ada0d8"
      },
      "base/model.safetensors.index.json": {
        "bytes": 17719,
        "sha256": "a7c27672b42c6adc1dd75a632b6d50f95dd5887d55fa02b1676bb0ebdeefe0e3",
        "url": "https://huggingface.co/tiiuae/falcon-7b/resolve/ec89142b67d748a1865ea4451372db8313ada0d8/model.safetensors.index.json",
        "revision": "ec89142b67d748a1865ea4451372db8313ada0d8"
      },
      "base/model-00001-of-00002.safetensors": {
        "bytes": 9950994832,
        "sha256": "02ebbe9c76d5f574bbacc8193a21e08246905e05b8e66d21a3149fd0ead3a636",
        "url": "https://huggingface.co/tiiuae/falcon-7b/resolve/ec89142b67d748a1865ea4451372db8313ada0d8/model-00001-of-00002.safetensors",
        "revision": "ec89142b67d748a1865ea4451372db8313ada0d8"
      },
      "base/model-00002-of-00002.safetensors": {
        "bytes": 4483408144,
        "sha256": "b40ecba13b10a02a867975f8b6d76833e71987a49539d09e9d276ff9ef955a45",
        "url": "https://huggingface.co/tiiuae/falcon-7b/resolve/ec89142b67d748a1865ea4451372db8313ada0d8/model-00002-of-00002.safetensors",
        "revision": "ec89142b67d748a1865ea4451372db8313ada0d8"
      },
      "base/tokenizer.json": {
        "bytes": 2734130,
        "sha256": "d6c5cdac1421ea998722aa88ea1cb630b2a9ec63bf8a85331bb3d9d321507186",
        "url": "https://huggingface.co/tiiuae/falcon-7b/resolve/ec89142b67d748a1865ea4451372db8313ada0d8/tokenizer.json",
        "revision": "ec89142b67d748a1865ea4451372db8313ada0d8"
      },
      "base/tokenizer_config.json": {
        "bytes": 287,
        "sha256": "956d99c7b9a195e5c3eea5074cb3571b761282f2e621d804817b86dbcf6e2385",
        "url": "https://huggingface.co/tiiuae/falcon-7b/resolve/ec89142b67d748a1865ea4451372db8313ada0d8/tokenizer_config.json",
        "revision": "ec89142b67d748a1865ea4451372db8313ada0d8"
      },
      "base/special_tokens_map.json": {
        "bytes": 281,
        "sha256": "c0bf83db1644ea3fdcd1a8a68172a0a6c8c3956da922e1e75c47b97e8315433a",
        "url": "https://huggingface.co/tiiuae/falcon-7b/resolve/ec89142b67d748a1865ea4451372db8313ada0d8/special_tokens_map.json",
        "revision": "ec89142b67d748a1865ea4451372db8313ada0d8"
      },
      "adapter/adapter_config.json": {
        "bytes": 437,
        "sha256": "2021ee546fb67a56034e57403b180e655b67bff776ead10102610278e5771243",
        "url": "https://huggingface.co/FinGPT/fingpt-mt_falcon-7b_lora/resolve/69f69de456efdbed5729e797cf8991524a30f977/adapter_config.json",
        "revision": "69f69de456efdbed5729e797cf8991524a30f977"
      },
      "adapter/adapter_model.bin": {
        "bytes": 4729725,
        "sha256": "5ff09b168e9de46a89437825fad845fc3de0641963adf1c8d6da3a2883fd58a9",
        "url": "https://huggingface.co/FinGPT/fingpt-mt_falcon-7b_lora/resolve/69f69de456efdbed5729e797cf8991524a30f977/adapter_model.bin",
        "revision": "69f69de456efdbed5729e797cf8991524a30f977"
      }
    }
    PYMANIFEST
    .venv/bin/python - <<'PYHASH'
    import pathlib,json,hashlib
    for name,info in json.load(open('asset-manifest.json')).items():
     p=pathlib.Path(name);digest=hashlib.sha256()
     with p.open('rb') as stream:
      for chunk in iter(lambda:stream.read(1024*1024),b''):digest.update(chunk)
     assert p.stat().st_size==info['bytes'] and digest.hexdigest()==info['sha256'],name
    print('All ten exact base/adapter asset checks passed.')
    PYHASH

    Expected result: Both base shards, native tokenizer/config/index/generation files and adapter config/weights pass exact length/hash checks. Adapter alone is incomplete; no successful model load is preclaimed.

Configure

  1. 1. Create a stable private local key and original fixtures

    Preserve an existing private key. These four original fictional fixtures use the exact native task instructions. Semantic criteria are for human inspection, not forced gold outputs or claimed quality.

    Command
    cd "$HOME/fingpt-falcon"
    umask 077
    if [ ! -e .api-key ]; then openssl rand -hex 32 > .api-key; fi
    chmod 600 .api-key
    test -s .api-key || { echo "Restore empty service key before continuing"; exit 1; }
    cat > synthetic-fixtures.json <<'PYFIXTURES'
    {
      "sentiment": {
        "instruction": "What is the sentiment of this news? Please choose an answer from {negative/neutral/positive}.",
        "input": "The fictional Cedar Tools company reported stronger sales and lower costs.",
        "semantic_criterion": "Assess whether the answer expresses the positive sentiment supported by the stronger-sales/lower-costs sentence; no real investment conclusion."
      },
      "relation": {
        "instruction": "Given phrases that describe the relationship between two words/phrases as options, extract the word/phrase pair and the corresponding lexical relationship between them from the input text. The output format should be \"relation1: word1, word2; relation2: word3, word4\". Options: product/material produced, manufacturer, distributed by, industry, position held, original broadcaster, owned by, founded by, distribution format, headquarters location, stock exchange, currency, parent organization, chief executive officer, director/manager, owner of, operator, member of, employer, chairperson, platform, subsidiary, legal form, publisher, developer, brand, business division, location of formation, creator.",
        "input": "Mira Vale is the chief executive officer of the fictional Cedar Motors company.",
        "semantic_criterion": "Assess whether the answer links Mira Vale and Cedar Motors with the chief-executive-officer relation; preserve the model actual formatting and record any incorrect pair/relation."
      },
      "headline": {
        "instruction": "Does the news headline talk about price going up? Please choose an answer from {Yes/No}.",
        "input": "Fictional copper prices rise in a classroom market example.",
        "semantic_criterion": "Assess whether the answer recognizes that the synthetic headline explicitly describes a price increase; no price prediction."
      },
      "ner": {
        "instruction": "Please extract entities and their types from the input sentence, entity types should be chosen from {person/organization/location}.",
        "input": "Mira Vale works for the fictional Cedar Motors company in Riverton.",
        "semantic_criterion": "Assess whether the answer identifies Mira Vale as person, Cedar Motors as organization and Riverton as location, without inventing entities."
      }
    }
    PYFIXTURES

    Expected result: Private existing key remains stable and four synthetic task definitions are saved. No real financial/customer data or actions are included.

  2. 2. Write the native base and strict adapter loader

    Reader-authored research wrapper uses explicit Falcon native classes and local fast tokenizer, avoiding checkpoint auto_map remote code. It checks the full local asset manifest, exact LoRA key/shape/finiteness sets and values after load. No vocabulary resize or randomly initialized PAD token is introduced.

    Command
    cd "$HOME/fingpt-falcon"
    cat > fingpt_server.py <<'PYSERVER1'
    """Reader-authored fixed synthetic FinGPT Falcon7B+LoRA research service; no financial actions."""
    import hashlib,hmac,json,pathlib
    from http.server import BaseHTTPRequestHandler,HTTPServer
    ROOT=pathlib.Path(__file__).resolve().parent
    PORT=8995
    FIXTURES=json.loads((ROOT/'synthetic-fixtures.json').read_text())
    MAX_CONTEXT=2048
    MAX_OUTPUT=128
    
    def native_prompt(fixture):
        f=FIXTURES[fixture]
        return 'Instruction: {instruction}\nInput: {input}\nAnswer: '.format(**f)
    
    def validate_completion(fixture,result):
        prompt_count,generated_ids,answer=result
        if type(prompt_count) is not int or not 1<=prompt_count<=MAX_CONTEXT-MAX_OUTPUT:raise ValueError('prompt_budget')
        if type(generated_ids) is not list or not 2<=len(generated_ids)<MAX_OUTPUT or any(type(i) is not int or i<0 for i in generated_ids) or generated_ids[-1]!=11 or 11 in generated_ids[:-1]:raise ValueError('unfinished_or_capped_output')
        if not isinstance(answer,str) or not answer.strip() or len(answer.encode())>4096:raise ValueError('answer_shape')
        return {'fixture':fixture,'answer':answer,'prompt_tokens':prompt_count,'generated_tokens_including_eos':len(generated_ids),
                'context_tokens':MAX_CONTEXT,'output_cap':MAX_OUTPUT,'ended_with_eos':True,
                'semantic_criterion':FIXTURES[fixture]['semantic_criterion'],'semantic_quality_observed':False,'financial_action_executed':False}
    
    def validate_base_loading_info(info):
        fields={'missing_keys','unexpected_keys','mismatched_keys','error_msgs'}
        if not isinstance(info,dict) or set(info)!=fields:
            raise RuntimeError('base_loading_diagnostics_shape')
        for field in fields:
            if not isinstance(info[field],list) or info[field]:
                raise RuntimeError('base_loading_diagnostics:'+field)
    
    def make_encoder():
        import os
        os.environ['HF_HUB_OFFLINE']='1';os.environ['TRANSFORMERS_OFFLINE']='1'
        import torch
        from transformers import FalconConfig,FalconForCausalLM,PreTrainedTokenizerFast
        from peft import LoraConfig,get_peft_model,get_peft_model_state_dict,set_peft_model_state_dict
        torch.set_num_threads(8)
        manifest=json.loads((ROOT/'asset-manifest.json').read_text())
        for name,info in manifest.items():
            file=ROOT/name;digest=hashlib.sha256()
            with file.open('rb') as stream:
                for chunk in iter(lambda:stream.read(1024*1024),b''):digest.update(chunk)
            if file.stat().st_size!=info['bytes'] or digest.hexdigest()!=info['sha256']:raise RuntimeError('asset_mismatch:'+name)
        cfg=FalconConfig.from_pretrained(ROOT/'base',local_files_only=True)
        if not (cfg.model_type=='falcon' and cfg.hidden_size==4544 and cfg.num_hidden_layers==32 and cfg.num_attention_heads==71 and cfg.multi_query and not cfg.new_decoder_architecture and cfg.parallel_attn):raise RuntimeError('wrong_base_architecture')
        tokenizer=PreTrainedTokenizerFast.from_pretrained(ROOT/'base',local_files_only=True)
        if tokenizer.eos_token_id!=11 or tokenizer.model_max_length!=2048:raise RuntimeError('tokenizer_configuration')
        base,loading_info=FalconForCausalLM.from_pretrained(ROOT/'base',config=cfg,local_files_only=True,use_safetensors=True,
            dtype=torch.float32,attn_implementation='eager',low_cpu_mem_usage=True,output_loading_info=True)
        validate_base_loading_info(loading_info)
        base=base.to('cpu')
        lora=LoraConfig.from_pretrained(ROOT/'adapter',local_files_only=True)
        if lora.r!=8 or lora.lora_alpha!=32 or lora.bias!='none' or set(lora.target_modules)!={'query_key_value'} or lora.modules_to_save is not None:raise RuntimeError('wrong_adapter_configuration')
        model=get_peft_model(base,lora)
        target=get_peft_model_state_dict(model,save_embedding_layers=False)
        stored=torch.load(ROOT/'adapter/adapter_model.bin',map_location='cpu',weights_only=True)
        if not isinstance(stored,dict) or len(stored)!=64 or set(stored)!=set(target):raise RuntimeError('adapter_keyset_mismatch')
        for key,tensor in stored.items():
            if not isinstance(tensor,torch.Tensor) or tuple(tensor.shape)!=tuple(target[key].shape) or not torch.isfinite(tensor).all():raise RuntimeError('adapter_shape_or_finiteness')
        status=set_peft_model_state_dict(model,stored)
        if status.unexpected_keys:raise RuntimeError('unexpected_adapter_keys')
        actual=get_peft_model_state_dict(model,save_embedding_layers=False)
        for key,tensor in stored.items():
            if not torch.equal(actual[key].cpu(),tensor.to(actual[key].dtype)):raise RuntimeError('adapter_value_load_mismatch')
        del target,stored,actual,base
        model=model.float().eval()
        for param in model.parameters():param.requires_grad_(False)
        def encode(fixture):
            inputs=tokenizer(native_prompt(fixture),return_tensors='pt',truncation=False,return_token_type_ids=False)
            n=int(inputs['input_ids'].shape[1])
            if not 1<=n<=MAX_CONTEXT-MAX_OUTPUT:raise ValueError('input_budget')
            with torch.inference_mode():
                result=model.generate(**inputs,max_new_tokens=MAX_OUTPUT,do_sample=False,num_beams=1,
                    eos_token_id=11,pad_token_id=11,use_cache=True)
            if result.ndim!=2 or result.shape[0]!=1 or not torch.equal(result[0,:n],inputs['input_ids'][0]):raise RuntimeError('generation_prefix')
            ids=result[0,n:].tolist();answer=tokenizer.decode(ids,skip_special_tokens=True)
            return n,ids,answer
        return encode
    
    PYSERVER1

    Expected result: Native loading/generation section saved; reader startup will stop on any asset/architecture/adapter/value mismatch.

  3. 3. Append the private serial request boundary

    Only four fixed fixture IDs are accepted; no arbitrary prompt, URL, path, schema or tool execution. Native per-request generation is serial, unpadded and bounded. Socket reads have a timeout; model generation has no execution deadline.

    Command
    cd "$HOME/fingpt-falcon"
    cat >> fingpt_server.py <<'PYSERVER2'
    def create_server(encoder, key, port=PORT):
        if not isinstance(key, str) or len(key) != 64 or any(c not in '0123456789abcdef' for c in key):
            raise ValueError('key_format')
    
        class Handler(BaseHTTPRequestHandler):
            def setup(self):
                super().setup()
                self.connection.settimeout(5)
    
            def log_message(self, *_):
                pass  # Do not log Bearer keys or request bodies.
    
            def reply(self, status, obj):
                data = json.dumps(obj, allow_nan=False, separators=(',', ':')).encode()
                self.send_response(status)
                self.send_header('Content-Type', 'application/json')
                self.send_header('Content-Length', str(len(data)))
                self.send_header('Connection', 'close')
                self.end_headers()
                self.wfile.write(data)
                self.close_connection = True
    
            def authorized(self):
                values = self.headers.get_all('Authorization', [])
                return len(values) == 1 and hmac.compare_digest(values[0].encode(), ('Bearer ' + key).encode())
    
            def do_GET(self):
                if not self.authorized():
                    return self.reply(401, {'error': 'unauthorized'})
                if self.path != '/health':
                    return self.reply(404, {'error': 'not_found'})
                return self.reply(200, {'ready': True, 'context_tokens': 2048,
                                        'output_cap': 128})
    
            def do_POST(self):
                if not self.authorized():
                    return self.reply(401, {'error': 'unauthorized'})
                if self.path != '/v1/multitask':
                    return self.reply(404, {'error': 'not_found'})
                if self.headers.get('Transfer-Encoding') is not None:
                    return self.reply(400, {'error': 'transfer_encoding_unsupported'})
                lengths = self.headers.get_all('Content-Length', [])
                if len(lengths) != 1:
                    return self.reply(411, {'error': 'content_length_required'})
                raw = lengths[0]
                if not raw or len(raw) > 4 or any(c not in '0123456789' for c in raw):
                    return self.reply(413, {'error': 'invalid_or_excessive_length'})
                n = int(raw)
                if n < 1 or n > 256:
                    return self.reply(413, {'error': 'body_limit'})
                if self.headers.get_content_type() != 'application/json':
                    return self.reply(415, {'error': 'json_required'})
                try:
                    body = self.rfile.read(n)
                except (TimeoutError, OSError):
                    return self.reply(408, {'error': 'body_timeout'})
                if len(body) != n:
                    return self.reply(400, {'error': 'incomplete_body'})
                try:
                    def unique(pairs):
                        obj = {}
                        for k, v in pairs:
                            if k in obj:
                                raise ValueError('duplicate_key')
                            obj[k] = v
                        return obj
                    request = json.loads(body.decode('utf-8'), object_pairs_hook=unique,
                                         parse_constant=lambda _: (_ for _ in ()).throw(ValueError('constant')))
                except (ValueError, UnicodeError, RecursionError):
                    return self.reply(400, {'error': 'invalid_json'})
                if type(request) is not dict or set(request)!={'fixture'} or type(request['fixture']) is not str or request['fixture'] not in FIXTURES:
                    return self.reply(400, {'error': 'fixed_fixture_required'})
                try:
                    result = validate_completion(request['fixture'],encoder(request['fixture']))
                except Exception:
                    return self.reply(500, {'error': 'generation_or_protocol_failure'})
                return self.reply(200, result)
    
        return HTTPServer(('127.0.0.1', port), Handler)
    
    
    if __name__=='__main__':
        encoder=make_encoder()
        with create_server(encoder,(ROOT/'.api-key').read_text().strip()) as server:server.serve_forever()
    PYSERVER2

    Expected result: Complete custom loopback service saved; no external model imports occur until reader start.

Start the model

  1. 1. Start the private FP32 CPU multitask service

    Run in foreground. Native Falcon eager CPU FP32 and eight inference threads are explicit; LoRA stays applied at runtime without a quantized or merged substitute. HF/Transformers offline flags apply. The full 7B base and all strict adapter checks must succeed before HTTP readiness.

    Command
    cd "$HOME/fingpt-falcon"
    HF_HUB_OFFLINE=1 TRANSFORMERS_OFFLINE=1 .venv/bin/python fingpt_server.py

    Expected result: After actual reader execution and successful native checks, loopback 8995 listens. Memory fit, loading success, speed and answer quality are not preclaimed.

Connect to your endpoint

http://127.0.0.1:8995/v1/multitask

Same trusted desktop loopback only.

Access: loopback. Private reader-generated Bearer key required for health and POST. Exact JSON fixture selector must be sentiment/relation/headline/ner. Response is actual new-token answer plus counts and human semantic criterion; no chat API/provider credential or financial action.

Verify the setup

  1. 1. Inspect all four native task answers without forcing semantic gold labels

    Use a second terminal on the server. Check authenticated readiness, request each fixed fixture and validate complete EOS-terminated new-token output within the full 2,048-token context. Read each actual answer against its supplied synthetic semantic criterion and record correctness separately. Protocol-valid output can be wrong; the wrapper deliberately does not force a gold sentiment/entity/relation answer.

    Command
    set -e
    cd "$HOME/fingpt-falcon"
    FINGPT_KEY="$(cat .api-key)"
    curl --fail http://127.0.0.1:8995/health -H "Authorization: Bearer $FINGPT_KEY"
    for FIXTURE in sentiment relation headline ner; do
     curl --fail http://127.0.0.1:8995/v1/multitask -H "Authorization: Bearer $FINGPT_KEY" -H 'Content-Type: application/json' -d "{\"fixture\":\"$FIXTURE\"}" -o "$FIXTURE.json"
    done
    curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8995/health
    unset FINGPT_KEY
    .venv/bin/python - <<'PYVERIFY'
    import json
    for fixture in ["sentiment","relation","headline","ner"]:
     d=json.load(open(fixture+".json"));assert d["fixture"]==fixture and d["ended_with_eos"] is True
     assert d["financial_action_executed"] is False and d["semantic_quality_observed"] is False
     assert 1<=d["prompt_tokens"]<=1920 and 2<=d["generated_tokens_including_eos"]<128
     assert isinstance(d["answer"],str) and d["answer"].strip()
     print(fixture,"actual answer:",d["answer"],"\nInspect against:",d["semantic_criterion"])
    print("Record actual semantic assessment separately; protocol completion is not financial correctness.")
    PYVERIFY

    Expected result: Four actual answer records pass EOS/budget/shape checks and missing-key health returns401. Read and record semantic failures honestly; no exact gold answer or measured multitask accuracy is claimed.

Performance evidence

No compatible measurement available. Documented support and estimated memory do not establish response speed.

Limits and troubleshooting

  • Source-documented native CPU setup only; no weights, install/build, model imports/inference, memory fit, performance or semantic accuracy observations.
  • FinGPT is a family. This exact MIT Falcon multitask adapter uses the explicitly notebook-mapped TII Falcon-7B base; legacy adapter config local path has no pinned base revision, so both selected revisions are independently pinned and source linkage disclosed. Other seven linked adapters remain open.
  • The adapter is 4,729,725 bytes, not a standalone 7B model. Two mandatory base shards total 14,434,402,976 bytes; composite weights 14,439,132,701 bytes exclude runtime/cache/loading overhead. No full combined digest or downloaded weight-body proof is invented.
  • Native checkpoint is BF16 metadata, while this recipe runs full FP32 CPU eager compute and FP32 cache with LoRA. No CUDA/8bit/bitsandbytes assumption, base-card GPU memory claim or sibling-performance transfer.64 GiB RAM, 80 GiB disk and eight threads are allocations, not fit.
  • Explicit native Falcon classes avoid executing checkpoint auto_map custom code. Exact plain tokenizer and raw Instruction/Input/Answer prompt are used; there is no chat/thinking template. Existing EOS11 is pad for one unpadded sequence, with no extra PAD token or embedding resize.
  • The model tokenizer and base card declare 2,048-token sequence length. The complete native prompt is counted without truncation and limited to 1,920, reserving 128 new tokens. Require native EOS11 and fewer than 128 generated IDs; cap-reaching output is conservatively rejected even if it ends with EOS at the cap.
  • Adapter loading uses torch.load(weights_only=True) after exact source-pinned SHA checks. The custom loader validates 64 exact LoRA parameter names/shapes/finiteness against current PEFT expected state, then compares loaded adapter values; missing base keys from adapter-only loading are not falsely described as strict full-model loading.
  • Native notebook uses older Transformers/PEFT and GPU 8-bit examples. Archived modern native Falcon/PEFT sources support the selected target/API, and exact package metadata constraints align; actual Python 3.12 install/operator/runtime compatibility remains unexecuted. Transitive/system resolution is recorded, not asserted reproducibly locked.
  • Four original fictional sentiment/relation/headline/NER tasks exercise native interfaces. Complete EOS/protocol validity is not correctness, calibration, financial advice, trading authorization or a benchmark. Human assessment records actual outputs, including incorrect answers; no semantic gold is forced by the server.
  • Private serial HTTPServer has fixed inputs/auth/loopback/body and socket limits, but no inference deadline/TLS/public multiuser resilience. No prompt upload, external tool, URL or financial action is performed. Client timeout does not cancel native work.
  • Longer contexts, other adapters/model sizes, GPU/quantization, broader task inputs/quality evaluations and real financial decision use require separate qualification and are not excluded or completed by this pair.
Base, tokenizer or adapter mismatch
Stop. Verify both base shards, exact token/config files, independently pinned adapter and native runtime. Do not substitute Falcon-Instruct, relax adapter key/shape/value checks or enable unreviewed remote code.
EOS missing, output cap or prompt overflow
Record the failure and preserve exact outputs. Do not silently truncate prompts, accept partial answers or raise the configuration budget. EOS completion is separate from semantic correctness.
Incorrect synthetic sentiment, relation, headline or entities
Record the actual semantic error without forcing gold labels or relaxing the criterion. This source-only interface exercise provides no financial correctness or decision authorization.
OOM, slow CPU or package error
Stop and record the actual environment/error. Full FP32 expansion/cache/loading can exceed artifact sizes;64GiB allocation is not measured fit or throughput. New precision/hardware/runtime requires requalification.
401 or connection refused
Check foreground readiness, private key and loopback/SSH boundary. Keep public8995 closed and never print/share the key.

Stop the model

  1. 1. Stop the native multitask process

    Press Ctrl+C in foreground and unset keys in each shell. Confirm loopback 8995 closes.

    Command
    unset FINGPT_KEY

    Expected result: Private Python model service stops; no financial action or external tool was executed.

Uninstall

  1. 1. Remove dedicated research files

    Back up desired actual outputs/licensing records, confirm exact directory and remove only this workspace. Shared Ubuntu packages remain.

    Command
    rm -r -- "$HOME/fingpt-falcon"

    Expected result: Dedicated base/adapter, tokenizer/config/manifest, virtualenv, wrapper, fixtures/results and private key removed.

Sources and verification

Sources checked Oct 16, 2026. Verification source

Compare this configuration
Cloud serverDocumented setupSources checked Oct 16, 2026

Run FinGPT Falcon-7B multitask analysis on a private CPU VM

Load the exact Falcon-7B base and FinGPT multitask LoRA as a full FP32 CPU model. A private serial service returns answers for four original synthetic sentiment, relation, headline and named-entity fixtures using the published Instruction/Input/Answer format. Eight threads, one sequence, 2,048 total tokens and a 128-token output cap. Actual answer quality, memory fit and speed remain unmeasured.

Hardware
AWS r7i.2xlarge, 64 GiB RAM, Ubuntu x86_64
Runtime
Native Falcon7B plus FinGPT LoRA private CPU multitask research service Transformers4.57.6;PEFT0.17.1;torch2.6.0+cpu;accelerate1.10.1;tokenizers0.22.2;Python3.12 · CPU
Model format
PyTorch LoRA adapter with required safetensors base · Full base and LoRA CPUFP32; native base checkpoint declares BF16; no8bit loading · No quantization; reader full base+adapter CPUFP32
Workload
2,048 token context · 1 concurrent

Based on source documentation; this setup has not been executed by OpenTools. Memory: unknown. No compatible measurement available.

Read the complete setup guide

Before you start

  • Use an owned AWS r7i.2xlarge Ubuntu 24.04 x86_64 VM in us-east-1, 64 GiB RAM, eight vCPUs and 80 GiB gp3. Existing SSH access must be restricted to your client; keep public port 8995 closed. Provisioning/billing are reader actions.
  • Read both exact MIT adapter and Apache-2.0 base terms; preserve notices. Public native base and adapter are independently pinned. No gate or terms acceptance is performed for the reader.
  • This is a source-documented low-stakes educational multitask experiment with fictional original inputs, not investment advice, a trading tool, a financial forecast or measured accuracy. Actual semantic assessment is separate from protocol completion.
  • Use the exact FinGPT Falcon multitask LoRA and native tiiuae/falcon-7b base. The adapter config names a legacy local base path; exact publisher notebook explicitly maps falcon to the TII base. Other seven README-linked adapters and broader supported scope remain open.

Exact model and requirements

Artifact:
FinGPT / AI4Finance Foundation (adapter); TII (required Falcon-7B base) / Exact FinGPT Falcon-7B multitask LoRA plus required native Falcon-7B base · checkpoint FinGPT/fingpt-mt_falcon-7b_lora
Publisher revision:
69f69de456efdbed5729e797cf8991524a30f977
Artifact digest:
sha256:5ff09b168e9de46a89437825fad845fc3de0641963adf1c8d6da3a2883fd58a9
Download size:
Unknown
Memory requirement (unknown):
Unknown — No full-process peak measured for full Falcon7B CPUFP32, LoRA, FP32cache and runtime/OS buffers.
System RAM / disk:
Unknown / Unknown
Placement:
single device. One CPU host, no tensor/pipeline sharding. Whole native base, LoRA and generation run on CPU; no GPU/disk offload.
KV cache:
FP32 native Falcon multi-query attention cache; exact process/cache peak unmeasured.
Workload:
2,048 token context; Unknown; Unknown; concurrency 1; batch 1; cache cold; repetitions Unknown.
Tokenizer:
Exact native Falcon PreTrainedTokenizerFast; no chat template or added vocabulary · ec89142b67d748a1865ea4451372db8313ada0d8;tokenizers0.22.2
Sampling / reasoning:
Native notebook uses greedy do_sampleFalse. This author uses num_beams1, max_new_tokens128, EOS/pad11 and no sampling; require EOS and fewer than128 generated tokens, then decode only new IDs. No native confidence/calibration or correctness score. Plain native Instruction:... / Input:... / Answer: prompt from exact publisher notebook. Four model-supported tasks share one fixed-fixture service. No financial recommendation, forecasting, chat/thinking template or execution. Full2048totalcontext comes from native basecard/tokenizer; input+128cap must fit. Single unpadded sequence uses existing EOS as pad without adding a random PAD embedding.
Runtime prerequisites:
Ubuntu24.04 x86_64; See prerequisites above.

Official artifact · License

The exact FinGPT adapter card explicitly declares MIT; the parent FinGPT repository includes actual MIT text. Required TII Falcon-7B base card explicitly grants Apache-2.0, whose full license is archived. Retain applicable MIT copyright/permission notices and Apache license/NOTICE/change notices and patent conditions. No financial correctness, endorsement, trading authorization or legal clearance is granted. Original synthetic fixtures contain no real customer or trading data.

  • Both required base shards total 14,434,402,976 bytes; adapter adds 4,729,725 bytes, total 14,439,132,701 published weight bytes. Individual digests are not a measured combined model or memory figure.
  • 64 GiB RAM, 80 GiB disk and eight threads/vCPUs are planning allocations, not measured minima or proven fit. CPU FP32 expansion, loading transients, cache and OS add overhead; native base GPU16GB guidance is not CPU fit evidence.

One-time setup and hardware

hardware
Not applicable — AWS hardware acquisition is included in compute rental; no purchased GPU required. Any separate hardware cost is not applicable.
AWS hardware acquisition is included in compute rental; no purchased GPU required. Any separate hardware cost is not applicable. Tax: unknown.
setup
Unknown — Initial provisioning/build time and labor cost are unknown.
Initial provisioning/build time and labor cost are unknown. Tax: unknown.

Recurring costs

compute
$0.53 / hour
AWS published us-east-1 Linux On-Demand quote USD 0.5292 per billed instance-hour, no paid preinstalled software. Eight billed hours cost USD 4.2336; 24 hours USD 12.7008 compute. Idle running hours bill. No discount, Spot or reservation assumed. Storage, egress, tax and administration additional; capacity unknown. Region: us-east-1. SKU: r7i.2xlarge Linux On-Demand. Tax: excluded. Price dated Oct 15, 2026. Price source
storage
$0.08 / GB month
Captured us-east-1 gp3 quote USD 0.08 per GB-month, with GB defined as 1024^3 bytes. Selected 80 GiB root volume costs USD 6.40 per full month, prorated by provisioned duration, at baseline 3000 IOPS and 125 MB/s. No provisioned extras assumed; retained snapshots/resources separate. Storage persists after stop; tax excluded. Region: us-east-1. SKU: EBS gp3 baseline 3000 IOPS / 125 MB/s. Tax: excluded. Price dated Oct 16, 2026. Price source
egress
Unknown — Data transfer price, allowances and traffic volume are unknown.
Data transfer price, allowances and traffic volume are unknown. Tax: unknown.
administration
Unknown — Maintenance labor rate and hours are unknown.
Maintenance labor rate and hours are unknown. Tax: unknown.

Install the runtime

  1. 1. Prepare the native CPU environment

    Install pinned CPU Torch and compatible native Transformers/PEFT releases in a dedicated environment. The publisher notebook originally uses 4.32/0.5 and CUDA 8-bit examples; this source-qualified native CPU path uses 4.57.6/0.17.1 with full FP32 and no bitsandbytes or remote model code. Record resolved transitive/system versions and stop on pip check/import/load errors; nothing was installed by the author.

    Command
    set -e
    sudo apt-get update
    sudo apt-get install -y python3.12 python3.12-venv curl ca-certificates openssl
    mkdir -p "$HOME/fingpt-falcon/base" "$HOME/fingpt-falcon/adapter"
    cd "$HOME/fingpt-falcon"
    python3.12 -m venv .venv
    .venv/bin/python -m pip install 'https://download.pytorch.org/whl/cpu/torch-2.6.0%2Bcpu-cp312-cp312-linux_x86_64.whl#sha256=59e78aa0c690f70734e42670036d6b541930b8eabbaa18d94e090abf14cc4d91'
    .venv/bin/python -m pip install 'transformers==4.57.6' 'peft==0.17.1' 'accelerate==1.10.1' 'safetensors==0.5.3' 'tokenizers==0.22.2' 'huggingface-hub==0.36.0' 'numpy==2.2.3'
    .venv/bin/python -m pip check
    .venv/bin/python -m pip freeze > resolved-environment.txt

    Expected result: Exact direct packages resolve and pip check passes; CPU wheel hash is checked by pip. Save resolution and stop on errors. No GPU driver/compiler or quantizer is used.

Download the model

  1. 1. Download every required base and adapter asset

    Reader downloads only; the author fetched metadata/text, not weight bodies. Both base shards and the LoRA are mandatory. Stream-check exact byte lengths and SHA-256 before any model or PyTorch adapter load. Never replace the base with Falcon-Instruct or omit a shard.

    Command
    set -e
    cd "$HOME/fingpt-falcon"
    curl --fail --location 'https://huggingface.co/tiiuae/falcon-7b/resolve/ec89142b67d748a1865ea4451372db8313ada0d8/config.json' -o 'base/config.json'
    curl --fail --location 'https://huggingface.co/tiiuae/falcon-7b/resolve/ec89142b67d748a1865ea4451372db8313ada0d8/generation_config.json' -o 'base/generation_config.json'
    curl --fail --location 'https://huggingface.co/tiiuae/falcon-7b/resolve/ec89142b67d748a1865ea4451372db8313ada0d8/model.safetensors.index.json' -o 'base/model.safetensors.index.json'
    curl --fail --location 'https://huggingface.co/tiiuae/falcon-7b/resolve/ec89142b67d748a1865ea4451372db8313ada0d8/model-00001-of-00002.safetensors' -o 'base/model-00001-of-00002.safetensors'
    curl --fail --location 'https://huggingface.co/tiiuae/falcon-7b/resolve/ec89142b67d748a1865ea4451372db8313ada0d8/model-00002-of-00002.safetensors' -o 'base/model-00002-of-00002.safetensors'
    curl --fail --location 'https://huggingface.co/tiiuae/falcon-7b/resolve/ec89142b67d748a1865ea4451372db8313ada0d8/tokenizer.json' -o 'base/tokenizer.json'
    curl --fail --location 'https://huggingface.co/tiiuae/falcon-7b/resolve/ec89142b67d748a1865ea4451372db8313ada0d8/tokenizer_config.json' -o 'base/tokenizer_config.json'
    curl --fail --location 'https://huggingface.co/tiiuae/falcon-7b/resolve/ec89142b67d748a1865ea4451372db8313ada0d8/special_tokens_map.json' -o 'base/special_tokens_map.json'
    curl --fail --location 'https://huggingface.co/FinGPT/fingpt-mt_falcon-7b_lora/resolve/69f69de456efdbed5729e797cf8991524a30f977/adapter_config.json' -o 'adapter/adapter_config.json'
    curl --fail --location 'https://huggingface.co/FinGPT/fingpt-mt_falcon-7b_lora/resolve/69f69de456efdbed5729e797cf8991524a30f977/adapter_model.bin' -o 'adapter/adapter_model.bin'
    cat > asset-manifest.json <<'PYMANIFEST'
    {
      "base/config.json": {
        "bytes": 1048,
        "sha256": "ef0b96fb53bf7627eb115138bdfd36edb5661891816546f41ed91fb80f19ab31",
        "url": "https://huggingface.co/tiiuae/falcon-7b/resolve/ec89142b67d748a1865ea4451372db8313ada0d8/config.json",
        "revision": "ec89142b67d748a1865ea4451372db8313ada0d8"
      },
      "base/generation_config.json": {
        "bytes": 117,
        "sha256": "54e9b0cf5be679b3c9bdc430ad850a40961e27298530c48e7da9133c963569a9",
        "url": "https://huggingface.co/tiiuae/falcon-7b/resolve/ec89142b67d748a1865ea4451372db8313ada0d8/generation_config.json",
        "revision": "ec89142b67d748a1865ea4451372db8313ada0d8"
      },
      "base/model.safetensors.index.json": {
        "bytes": 17719,
        "sha256": "a7c27672b42c6adc1dd75a632b6d50f95dd5887d55fa02b1676bb0ebdeefe0e3",
        "url": "https://huggingface.co/tiiuae/falcon-7b/resolve/ec89142b67d748a1865ea4451372db8313ada0d8/model.safetensors.index.json",
        "revision": "ec89142b67d748a1865ea4451372db8313ada0d8"
      },
      "base/model-00001-of-00002.safetensors": {
        "bytes": 9950994832,
        "sha256": "02ebbe9c76d5f574bbacc8193a21e08246905e05b8e66d21a3149fd0ead3a636",
        "url": "https://huggingface.co/tiiuae/falcon-7b/resolve/ec89142b67d748a1865ea4451372db8313ada0d8/model-00001-of-00002.safetensors",
        "revision": "ec89142b67d748a1865ea4451372db8313ada0d8"
      },
      "base/model-00002-of-00002.safetensors": {
        "bytes": 4483408144,
        "sha256": "b40ecba13b10a02a867975f8b6d76833e71987a49539d09e9d276ff9ef955a45",
        "url": "https://huggingface.co/tiiuae/falcon-7b/resolve/ec89142b67d748a1865ea4451372db8313ada0d8/model-00002-of-00002.safetensors",
        "revision": "ec89142b67d748a1865ea4451372db8313ada0d8"
      },
      "base/tokenizer.json": {
        "bytes": 2734130,
        "sha256": "d6c5cdac1421ea998722aa88ea1cb630b2a9ec63bf8a85331bb3d9d321507186",
        "url": "https://huggingface.co/tiiuae/falcon-7b/resolve/ec89142b67d748a1865ea4451372db8313ada0d8/tokenizer.json",
        "revision": "ec89142b67d748a1865ea4451372db8313ada0d8"
      },
      "base/tokenizer_config.json": {
        "bytes": 287,
        "sha256": "956d99c7b9a195e5c3eea5074cb3571b761282f2e621d804817b86dbcf6e2385",
        "url": "https://huggingface.co/tiiuae/falcon-7b/resolve/ec89142b67d748a1865ea4451372db8313ada0d8/tokenizer_config.json",
        "revision": "ec89142b67d748a1865ea4451372db8313ada0d8"
      },
      "base/special_tokens_map.json": {
        "bytes": 281,
        "sha256": "c0bf83db1644ea3fdcd1a8a68172a0a6c8c3956da922e1e75c47b97e8315433a",
        "url": "https://huggingface.co/tiiuae/falcon-7b/resolve/ec89142b67d748a1865ea4451372db8313ada0d8/special_tokens_map.json",
        "revision": "ec89142b67d748a1865ea4451372db8313ada0d8"
      },
      "adapter/adapter_config.json": {
        "bytes": 437,
        "sha256": "2021ee546fb67a56034e57403b180e655b67bff776ead10102610278e5771243",
        "url": "https://huggingface.co/FinGPT/fingpt-mt_falcon-7b_lora/resolve/69f69de456efdbed5729e797cf8991524a30f977/adapter_config.json",
        "revision": "69f69de456efdbed5729e797cf8991524a30f977"
      },
      "adapter/adapter_model.bin": {
        "bytes": 4729725,
        "sha256": "5ff09b168e9de46a89437825fad845fc3de0641963adf1c8d6da3a2883fd58a9",
        "url": "https://huggingface.co/FinGPT/fingpt-mt_falcon-7b_lora/resolve/69f69de456efdbed5729e797cf8991524a30f977/adapter_model.bin",
        "revision": "69f69de456efdbed5729e797cf8991524a30f977"
      }
    }
    PYMANIFEST
    .venv/bin/python - <<'PYHASH'
    import pathlib,json,hashlib
    for name,info in json.load(open('asset-manifest.json')).items():
     p=pathlib.Path(name);digest=hashlib.sha256()
     with p.open('rb') as stream:
      for chunk in iter(lambda:stream.read(1024*1024),b''):digest.update(chunk)
     assert p.stat().st_size==info['bytes'] and digest.hexdigest()==info['sha256'],name
    print('All ten exact base/adapter asset checks passed.')
    PYHASH

    Expected result: Both base shards, native tokenizer/config/index/generation files and adapter config/weights pass exact length/hash checks. Adapter alone is incomplete; no successful model load is preclaimed.

Configure

  1. 1. Create a stable private local key and original fixtures

    Preserve an existing private key. These four original fictional fixtures use the exact native task instructions. Semantic criteria are for human inspection, not forced gold outputs or claimed quality.

    Command
    cd "$HOME/fingpt-falcon"
    umask 077
    if [ ! -e .api-key ]; then openssl rand -hex 32 > .api-key; fi
    chmod 600 .api-key
    test -s .api-key || { echo "Restore empty service key before continuing"; exit 1; }
    cat > synthetic-fixtures.json <<'PYFIXTURES'
    {
      "sentiment": {
        "instruction": "What is the sentiment of this news? Please choose an answer from {negative/neutral/positive}.",
        "input": "The fictional Cedar Tools company reported stronger sales and lower costs.",
        "semantic_criterion": "Assess whether the answer expresses the positive sentiment supported by the stronger-sales/lower-costs sentence; no real investment conclusion."
      },
      "relation": {
        "instruction": "Given phrases that describe the relationship between two words/phrases as options, extract the word/phrase pair and the corresponding lexical relationship between them from the input text. The output format should be \"relation1: word1, word2; relation2: word3, word4\". Options: product/material produced, manufacturer, distributed by, industry, position held, original broadcaster, owned by, founded by, distribution format, headquarters location, stock exchange, currency, parent organization, chief executive officer, director/manager, owner of, operator, member of, employer, chairperson, platform, subsidiary, legal form, publisher, developer, brand, business division, location of formation, creator.",
        "input": "Mira Vale is the chief executive officer of the fictional Cedar Motors company.",
        "semantic_criterion": "Assess whether the answer links Mira Vale and Cedar Motors with the chief-executive-officer relation; preserve the model actual formatting and record any incorrect pair/relation."
      },
      "headline": {
        "instruction": "Does the news headline talk about price going up? Please choose an answer from {Yes/No}.",
        "input": "Fictional copper prices rise in a classroom market example.",
        "semantic_criterion": "Assess whether the answer recognizes that the synthetic headline explicitly describes a price increase; no price prediction."
      },
      "ner": {
        "instruction": "Please extract entities and their types from the input sentence, entity types should be chosen from {person/organization/location}.",
        "input": "Mira Vale works for the fictional Cedar Motors company in Riverton.",
        "semantic_criterion": "Assess whether the answer identifies Mira Vale as person, Cedar Motors as organization and Riverton as location, without inventing entities."
      }
    }
    PYFIXTURES

    Expected result: Private existing key remains stable and four synthetic task definitions are saved. No real financial/customer data or actions are included.

  2. 2. Write the native base and strict adapter loader

    Reader-authored research wrapper uses explicit Falcon native classes and local fast tokenizer, avoiding checkpoint auto_map remote code. It checks the full local asset manifest, exact LoRA key/shape/finiteness sets and values after load. No vocabulary resize or randomly initialized PAD token is introduced.

    Command
    cd "$HOME/fingpt-falcon"
    cat > fingpt_server.py <<'PYSERVER1'
    """Reader-authored fixed synthetic FinGPT Falcon7B+LoRA research service; no financial actions."""
    import hashlib,hmac,json,pathlib
    from http.server import BaseHTTPRequestHandler,HTTPServer
    ROOT=pathlib.Path(__file__).resolve().parent
    PORT=8995
    FIXTURES=json.loads((ROOT/'synthetic-fixtures.json').read_text())
    MAX_CONTEXT=2048
    MAX_OUTPUT=128
    
    def native_prompt(fixture):
        f=FIXTURES[fixture]
        return 'Instruction: {instruction}\nInput: {input}\nAnswer: '.format(**f)
    
    def validate_completion(fixture,result):
        prompt_count,generated_ids,answer=result
        if type(prompt_count) is not int or not 1<=prompt_count<=MAX_CONTEXT-MAX_OUTPUT:raise ValueError('prompt_budget')
        if type(generated_ids) is not list or not 2<=len(generated_ids)<MAX_OUTPUT or any(type(i) is not int or i<0 for i in generated_ids) or generated_ids[-1]!=11 or 11 in generated_ids[:-1]:raise ValueError('unfinished_or_capped_output')
        if not isinstance(answer,str) or not answer.strip() or len(answer.encode())>4096:raise ValueError('answer_shape')
        return {'fixture':fixture,'answer':answer,'prompt_tokens':prompt_count,'generated_tokens_including_eos':len(generated_ids),
                'context_tokens':MAX_CONTEXT,'output_cap':MAX_OUTPUT,'ended_with_eos':True,
                'semantic_criterion':FIXTURES[fixture]['semantic_criterion'],'semantic_quality_observed':False,'financial_action_executed':False}
    
    def validate_base_loading_info(info):
        fields={'missing_keys','unexpected_keys','mismatched_keys','error_msgs'}
        if not isinstance(info,dict) or set(info)!=fields:
            raise RuntimeError('base_loading_diagnostics_shape')
        for field in fields:
            if not isinstance(info[field],list) or info[field]:
                raise RuntimeError('base_loading_diagnostics:'+field)
    
    def make_encoder():
        import os
        os.environ['HF_HUB_OFFLINE']='1';os.environ['TRANSFORMERS_OFFLINE']='1'
        import torch
        from transformers import FalconConfig,FalconForCausalLM,PreTrainedTokenizerFast
        from peft import LoraConfig,get_peft_model,get_peft_model_state_dict,set_peft_model_state_dict
        torch.set_num_threads(8)
        manifest=json.loads((ROOT/'asset-manifest.json').read_text())
        for name,info in manifest.items():
            file=ROOT/name;digest=hashlib.sha256()
            with file.open('rb') as stream:
                for chunk in iter(lambda:stream.read(1024*1024),b''):digest.update(chunk)
            if file.stat().st_size!=info['bytes'] or digest.hexdigest()!=info['sha256']:raise RuntimeError('asset_mismatch:'+name)
        cfg=FalconConfig.from_pretrained(ROOT/'base',local_files_only=True)
        if not (cfg.model_type=='falcon' and cfg.hidden_size==4544 and cfg.num_hidden_layers==32 and cfg.num_attention_heads==71 and cfg.multi_query and not cfg.new_decoder_architecture and cfg.parallel_attn):raise RuntimeError('wrong_base_architecture')
        tokenizer=PreTrainedTokenizerFast.from_pretrained(ROOT/'base',local_files_only=True)
        if tokenizer.eos_token_id!=11 or tokenizer.model_max_length!=2048:raise RuntimeError('tokenizer_configuration')
        base,loading_info=FalconForCausalLM.from_pretrained(ROOT/'base',config=cfg,local_files_only=True,use_safetensors=True,
            dtype=torch.float32,attn_implementation='eager',low_cpu_mem_usage=True,output_loading_info=True)
        validate_base_loading_info(loading_info)
        base=base.to('cpu')
        lora=LoraConfig.from_pretrained(ROOT/'adapter',local_files_only=True)
        if lora.r!=8 or lora.lora_alpha!=32 or lora.bias!='none' or set(lora.target_modules)!={'query_key_value'} or lora.modules_to_save is not None:raise RuntimeError('wrong_adapter_configuration')
        model=get_peft_model(base,lora)
        target=get_peft_model_state_dict(model,save_embedding_layers=False)
        stored=torch.load(ROOT/'adapter/adapter_model.bin',map_location='cpu',weights_only=True)
        if not isinstance(stored,dict) or len(stored)!=64 or set(stored)!=set(target):raise RuntimeError('adapter_keyset_mismatch')
        for key,tensor in stored.items():
            if not isinstance(tensor,torch.Tensor) or tuple(tensor.shape)!=tuple(target[key].shape) or not torch.isfinite(tensor).all():raise RuntimeError('adapter_shape_or_finiteness')
        status=set_peft_model_state_dict(model,stored)
        if status.unexpected_keys:raise RuntimeError('unexpected_adapter_keys')
        actual=get_peft_model_state_dict(model,save_embedding_layers=False)
        for key,tensor in stored.items():
            if not torch.equal(actual[key].cpu(),tensor.to(actual[key].dtype)):raise RuntimeError('adapter_value_load_mismatch')
        del target,stored,actual,base
        model=model.float().eval()
        for param in model.parameters():param.requires_grad_(False)
        def encode(fixture):
            inputs=tokenizer(native_prompt(fixture),return_tensors='pt',truncation=False,return_token_type_ids=False)
            n=int(inputs['input_ids'].shape[1])
            if not 1<=n<=MAX_CONTEXT-MAX_OUTPUT:raise ValueError('input_budget')
            with torch.inference_mode():
                result=model.generate(**inputs,max_new_tokens=MAX_OUTPUT,do_sample=False,num_beams=1,
                    eos_token_id=11,pad_token_id=11,use_cache=True)
            if result.ndim!=2 or result.shape[0]!=1 or not torch.equal(result[0,:n],inputs['input_ids'][0]):raise RuntimeError('generation_prefix')
            ids=result[0,n:].tolist();answer=tokenizer.decode(ids,skip_special_tokens=True)
            return n,ids,answer
        return encode
    
    PYSERVER1

    Expected result: Native loading/generation section saved; reader startup will stop on any asset/architecture/adapter/value mismatch.

  3. 3. Append the private serial request boundary

    Only four fixed fixture IDs are accepted; no arbitrary prompt, URL, path, schema or tool execution. Native per-request generation is serial, unpadded and bounded. Socket reads have a timeout; model generation has no execution deadline.

    Command
    cd "$HOME/fingpt-falcon"
    cat >> fingpt_server.py <<'PYSERVER2'
    def create_server(encoder, key, port=PORT):
        if not isinstance(key, str) or len(key) != 64 or any(c not in '0123456789abcdef' for c in key):
            raise ValueError('key_format')
    
        class Handler(BaseHTTPRequestHandler):
            def setup(self):
                super().setup()
                self.connection.settimeout(5)
    
            def log_message(self, *_):
                pass  # Do not log Bearer keys or request bodies.
    
            def reply(self, status, obj):
                data = json.dumps(obj, allow_nan=False, separators=(',', ':')).encode()
                self.send_response(status)
                self.send_header('Content-Type', 'application/json')
                self.send_header('Content-Length', str(len(data)))
                self.send_header('Connection', 'close')
                self.end_headers()
                self.wfile.write(data)
                self.close_connection = True
    
            def authorized(self):
                values = self.headers.get_all('Authorization', [])
                return len(values) == 1 and hmac.compare_digest(values[0].encode(), ('Bearer ' + key).encode())
    
            def do_GET(self):
                if not self.authorized():
                    return self.reply(401, {'error': 'unauthorized'})
                if self.path != '/health':
                    return self.reply(404, {'error': 'not_found'})
                return self.reply(200, {'ready': True, 'context_tokens': 2048,
                                        'output_cap': 128})
    
            def do_POST(self):
                if not self.authorized():
                    return self.reply(401, {'error': 'unauthorized'})
                if self.path != '/v1/multitask':
                    return self.reply(404, {'error': 'not_found'})
                if self.headers.get('Transfer-Encoding') is not None:
                    return self.reply(400, {'error': 'transfer_encoding_unsupported'})
                lengths = self.headers.get_all('Content-Length', [])
                if len(lengths) != 1:
                    return self.reply(411, {'error': 'content_length_required'})
                raw = lengths[0]
                if not raw or len(raw) > 4 or any(c not in '0123456789' for c in raw):
                    return self.reply(413, {'error': 'invalid_or_excessive_length'})
                n = int(raw)
                if n < 1 or n > 256:
                    return self.reply(413, {'error': 'body_limit'})
                if self.headers.get_content_type() != 'application/json':
                    return self.reply(415, {'error': 'json_required'})
                try:
                    body = self.rfile.read(n)
                except (TimeoutError, OSError):
                    return self.reply(408, {'error': 'body_timeout'})
                if len(body) != n:
                    return self.reply(400, {'error': 'incomplete_body'})
                try:
                    def unique(pairs):
                        obj = {}
                        for k, v in pairs:
                            if k in obj:
                                raise ValueError('duplicate_key')
                            obj[k] = v
                        return obj
                    request = json.loads(body.decode('utf-8'), object_pairs_hook=unique,
                                         parse_constant=lambda _: (_ for _ in ()).throw(ValueError('constant')))
                except (ValueError, UnicodeError, RecursionError):
                    return self.reply(400, {'error': 'invalid_json'})
                if type(request) is not dict or set(request)!={'fixture'} or type(request['fixture']) is not str or request['fixture'] not in FIXTURES:
                    return self.reply(400, {'error': 'fixed_fixture_required'})
                try:
                    result = validate_completion(request['fixture'],encoder(request['fixture']))
                except Exception:
                    return self.reply(500, {'error': 'generation_or_protocol_failure'})
                return self.reply(200, result)
    
        return HTTPServer(('127.0.0.1', port), Handler)
    
    
    if __name__=='__main__':
        encoder=make_encoder()
        with create_server(encoder,(ROOT/'.api-key').read_text().strip()) as server:server.serve_forever()
    PYSERVER2

    Expected result: Complete custom loopback service saved; no external model imports occur until reader start.

Start the model

  1. 1. Start the private FP32 CPU multitask service

    Run in foreground. Native Falcon eager CPU FP32 and eight inference threads are explicit; LoRA stays applied at runtime without a quantized or merged substitute. HF/Transformers offline flags apply. The full 7B base and all strict adapter checks must succeed before HTTP readiness.

    Command
    cd "$HOME/fingpt-falcon"
    HF_HUB_OFFLINE=1 TRANSFORMERS_OFFLINE=1 .venv/bin/python fingpt_server.py

    Expected result: After actual reader execution and successful native checks, loopback 8995 listens. Memory fit, loading success, speed and answer quality are not preclaimed.

Connect to your endpoint

http://127.0.0.1:8995/v1/multitask

VM loopback only. Optional SSH tunnel: ssh -N -L 8995:127.0.0.1:8995 USER@VM_IP; keep public port 8995 closed. Shown checks run on VM and use its private local key.

Access: loopback. Private reader-generated Bearer key required for health and POST. Exact JSON fixture selector must be sentiment/relation/headline/ner. Response is actual new-token answer plus counts and human semantic criterion; no chat API/provider credential or financial action.

Verify the setup

  1. 1. Inspect all four native task answers without forcing semantic gold labels

    Use a second terminal on the server. Check authenticated readiness, request each fixed fixture and validate complete EOS-terminated new-token output within the full 2,048-token context. Read each actual answer against its supplied synthetic semantic criterion and record correctness separately. Protocol-valid output can be wrong; the wrapper deliberately does not force a gold sentiment/entity/relation answer.

    Command
    set -e
    cd "$HOME/fingpt-falcon"
    FINGPT_KEY="$(cat .api-key)"
    curl --fail http://127.0.0.1:8995/health -H "Authorization: Bearer $FINGPT_KEY"
    for FIXTURE in sentiment relation headline ner; do
     curl --fail http://127.0.0.1:8995/v1/multitask -H "Authorization: Bearer $FINGPT_KEY" -H 'Content-Type: application/json' -d "{\"fixture\":\"$FIXTURE\"}" -o "$FIXTURE.json"
    done
    curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8995/health
    unset FINGPT_KEY
    .venv/bin/python - <<'PYVERIFY'
    import json
    for fixture in ["sentiment","relation","headline","ner"]:
     d=json.load(open(fixture+".json"));assert d["fixture"]==fixture and d["ended_with_eos"] is True
     assert d["financial_action_executed"] is False and d["semantic_quality_observed"] is False
     assert 1<=d["prompt_tokens"]<=1920 and 2<=d["generated_tokens_including_eos"]<128
     assert isinstance(d["answer"],str) and d["answer"].strip()
     print(fixture,"actual answer:",d["answer"],"\nInspect against:",d["semantic_criterion"])
    print("Record actual semantic assessment separately; protocol completion is not financial correctness.")
    PYVERIFY

    Expected result: Four actual answer records pass EOS/budget/shape checks and missing-key health returns401. Read and record semantic failures honestly; no exact gold answer or measured multitask accuracy is claimed.

Performance evidence

No compatible measurement available. Documented support and estimated memory do not establish response speed.

Limits and troubleshooting

  • Source-documented native CPU setup only; no weights, install/build, model imports/inference, memory fit, performance or semantic accuracy observations.
  • FinGPT is a family. This exact MIT Falcon multitask adapter uses the explicitly notebook-mapped TII Falcon-7B base; legacy adapter config local path has no pinned base revision, so both selected revisions are independently pinned and source linkage disclosed. Other seven linked adapters remain open.
  • The adapter is 4,729,725 bytes, not a standalone 7B model. Two mandatory base shards total 14,434,402,976 bytes; composite weights 14,439,132,701 bytes exclude runtime/cache/loading overhead. No full combined digest or downloaded weight-body proof is invented.
  • Native checkpoint is BF16 metadata, while this recipe runs full FP32 CPU eager compute and FP32 cache with LoRA. No CUDA/8bit/bitsandbytes assumption, base-card GPU memory claim or sibling-performance transfer.64 GiB RAM, 80 GiB disk and eight threads are allocations, not fit.
  • Explicit native Falcon classes avoid executing checkpoint auto_map custom code. Exact plain tokenizer and raw Instruction/Input/Answer prompt are used; there is no chat/thinking template. Existing EOS11 is pad for one unpadded sequence, with no extra PAD token or embedding resize.
  • The model tokenizer and base card declare 2,048-token sequence length. The complete native prompt is counted without truncation and limited to 1,920, reserving 128 new tokens. Require native EOS11 and fewer than 128 generated IDs; cap-reaching output is conservatively rejected even if it ends with EOS at the cap.
  • Adapter loading uses torch.load(weights_only=True) after exact source-pinned SHA checks. The custom loader validates 64 exact LoRA parameter names/shapes/finiteness against current PEFT expected state, then compares loaded adapter values; missing base keys from adapter-only loading are not falsely described as strict full-model loading.
  • Native notebook uses older Transformers/PEFT and GPU 8-bit examples. Archived modern native Falcon/PEFT sources support the selected target/API, and exact package metadata constraints align; actual Python 3.12 install/operator/runtime compatibility remains unexecuted. Transitive/system resolution is recorded, not asserted reproducibly locked.
  • Four original fictional sentiment/relation/headline/NER tasks exercise native interfaces. Complete EOS/protocol validity is not correctness, calibration, financial advice, trading authorization or a benchmark. Human assessment records actual outputs, including incorrect answers; no semantic gold is forced by the server.
  • Private serial HTTPServer has fixed inputs/auth/loopback/body and socket limits, but no inference deadline/TLS/public multiuser resilience. No prompt upload, external tool, URL or financial action is performed. Client timeout does not cancel native work.
  • Longer contexts, other adapters/model sizes, GPU/quantization, broader task inputs/quality evaluations and real financial decision use require separate qualification and are not excluded or completed by this pair.
Base, tokenizer or adapter mismatch
Stop. Verify both base shards, exact token/config files, independently pinned adapter and native runtime. Do not substitute Falcon-Instruct, relax adapter key/shape/value checks or enable unreviewed remote code.
EOS missing, output cap or prompt overflow
Record the failure and preserve exact outputs. Do not silently truncate prompts, accept partial answers or raise the configuration budget. EOS completion is separate from semantic correctness.
Incorrect synthetic sentiment, relation, headline or entities
Record the actual semantic error without forcing gold labels or relaxing the criterion. This source-only interface exercise provides no financial correctness or decision authorization.
OOM, slow CPU or package error
Stop and record the actual environment/error. Full FP32 expansion/cache/loading can exceed artifact sizes;64GiB allocation is not measured fit or throughput. New precision/hardware/runtime requires requalification.
401 or connection refused
Check foreground readiness, private key and loopback/SSH boundary. Keep public8995 closed and never print/share the key.

Stop the model

  1. 1. Stop the native multitask process

    Press Ctrl+C in foreground and unset keys in each shell. Close SSH tunnel; stopping Python does not stop VM/storage billing.

    Command
    unset FINGPT_KEY

    Expected result: Private Python model service stops; no financial action or external tool was executed.

Uninstall

  1. 1. Remove dedicated research files

    Back up desired actual outputs/licensing records, confirm exact directory and remove only this workspace. Shared Ubuntu packages remain.

    Command
    rm -r -- "$HOME/fingpt-falcon"

    Expected result: Dedicated base/adapter, tokenizer/config/manifest, virtualenv, wrapper, fixtures/results and private key removed.

Shut down cloud resources

  1. 1. End cloud billing resources

    In EC2 us-east-1, stop for later reuse or terminate this exact VM. Review Delete on termination for its root volume. Delete unwanted detached EBS volumes, snapshots and reserved/Elastic/public IP resources. Stopped VM storage and retained resources may still bill. Check Bills/Cost Explorer later for final usage.

    Expected result: Exact instance is stopped/terminated as intended; no unwanted attached/retained billed resources remain. Instance compute stops only after its lifecycle transition, not when Python service stops.

Sources and verification

Sources checked Oct 16, 2026. Verification source

Compare this configuration

Pricing and access

Open-source model family; runtime, hosting, and inference infrastructure costs depend on deployment.

AI4Finance Foundation logo

Open-source financial AI research and tooling

1 ModelsFounded 2020Global / open-source
View full profile