1+ use rust_lstm:: { LSTMNetwork , ModelMetadata , PersistentModel } ;
2+ use std:: fs;
3+
4+ fn main ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
5+ println ! ( "🔍 LSTM Model Internal Structure Inspection" ) ;
6+ println ! ( "============================================\n " ) ;
7+
8+ // Create a simple model for inspection
9+ println ! ( "🏗️ Creating a simple LSTM model..." ) ;
10+ let input_size = 3 ; // e.g., word embeddings of size 3
11+ let hidden_size = 4 ; // 4 hidden units
12+ let num_layers = 2 ; // 2-layer network
13+
14+ let network = LSTMNetwork :: new ( input_size, hidden_size, num_layers) ;
15+
16+ // Save it to examine the structure
17+ let metadata = ModelMetadata {
18+ model_name : "Language Model Example" . to_string ( ) ,
19+ version : "1.0.0" . to_string ( ) ,
20+ created_at : chrono:: Utc :: now ( ) . to_rfc3339 ( ) ,
21+ input_size,
22+ hidden_size,
23+ num_layers,
24+ total_epochs : 0 ,
25+ final_loss : None ,
26+ description : Some ( "Example LSTM for language modeling inspection" . to_string ( ) ) ,
27+ } ;
28+
29+ std:: fs:: create_dir_all ( "models" ) ?;
30+ network. save ( "models/inspection_model.json" , metadata. clone ( ) ) ?;
31+
32+ // Now inspect what's inside
33+ println ! ( "📊 WHAT'S STORED IN AN LSTM MODEL:" ) ;
34+ println ! ( "=================================\n " ) ;
35+
36+ inspect_architecture ( & network) ;
37+ inspect_parameters ( & network) ;
38+ inspect_file_contents ( ) ?;
39+ explain_llm_context ( ) ;
40+ calculate_parameter_count ( & network) ;
41+
42+ Ok ( ( ) )
43+ }
44+
45+ fn inspect_architecture ( network : & LSTMNetwork ) {
46+ println ! ( "🏗️ NETWORK ARCHITECTURE:" ) ;
47+ println ! ( " 📐 Input Size: {} (size of input vectors, e.g., word embeddings)" , network. input_size) ;
48+ println ! ( " 🧠 Hidden Size: {} (memory capacity per layer)" , network. hidden_size) ;
49+ println ! ( " 📚 Number of Layers: {} (depth of the network)" , network. num_layers) ;
50+ println ! ( " 🔄 Total Cells: {} LSTM cells" , network. num_layers) ;
51+ println ! ( ) ;
52+ }
53+
54+ fn inspect_parameters ( network : & LSTMNetwork ) {
55+ println ! ( "⚙️ PARAMETERS STORED FOR EACH LSTM CELL:" ) ;
56+ println ! ( "==========================================" ) ;
57+
58+ for ( layer_idx, cell) in network. get_cells ( ) . iter ( ) . enumerate ( ) {
59+ println ! ( "📦 Layer {} LSTM Cell:" , layer_idx) ;
60+
61+ // Each LSTM cell contains 4 gates: input, forget, cell, output
62+ println ! ( " 🔢 w_ih (Input→Hidden weights): {}×{} = {} parameters" ,
63+ cell. w_ih. shape( ) [ 0 ] , cell. w_ih. shape( ) [ 1 ] ,
64+ cell. w_ih. shape( ) [ 0 ] * cell. w_ih. shape( ) [ 1 ] ) ;
65+ println ! ( " • Controls how input affects all 4 gates (i,f,g,o)" ) ;
66+
67+ println ! ( " 🔄 w_hh (Hidden→Hidden weights): {}×{} = {} parameters" ,
68+ cell. w_hh. shape( ) [ 0 ] , cell. w_hh. shape( ) [ 1 ] ,
69+ cell. w_hh. shape( ) [ 0 ] * cell. w_hh. shape( ) [ 1 ] ) ;
70+ println ! ( " • Controls how previous hidden state affects gates" ) ;
71+
72+ println ! ( " ➕ b_ih (Input biases): {}×{} = {} parameters" ,
73+ cell. b_ih. shape( ) [ 0 ] , cell. b_ih. shape( ) [ 1 ] ,
74+ cell. b_ih. shape( ) [ 0 ] * cell. b_ih. shape( ) [ 1 ] ) ;
75+ println ! ( " • Bias terms for input transformations" ) ;
76+
77+ println ! ( " ➕ b_hh (Hidden biases): {}×{} = {} parameters" ,
78+ cell. b_hh. shape( ) [ 0 ] , cell. b_hh. shape( ) [ 1 ] ,
79+ cell. b_hh. shape( ) [ 0 ] * cell. b_hh. shape( ) [ 1 ] ) ;
80+ println ! ( " • Bias terms for hidden transformations" ) ;
81+
82+ println ! ( " 📏 Hidden Size: {}" , cell. hidden_size) ;
83+ println ! ( ) ;
84+ }
85+
86+ println ! ( "🧮 WHAT THESE PARAMETERS REPRESENT:" ) ;
87+ println ! ( " 🚪 4 Gates per cell (each gets 1/4 of the weights):" ) ;
88+ println ! ( " • Input Gate (i): Decides what new information to store" ) ;
89+ println ! ( " • Forget Gate (f): Decides what to discard from memory" ) ;
90+ println ! ( " • Cell Gate (g): Creates candidate values to add" ) ;
91+ println ! ( " • Output Gate (o): Decides what parts of memory to output" ) ;
92+ println ! ( ) ;
93+ }
94+
95+ fn inspect_file_contents ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
96+ println ! ( "📄 ACTUAL FILE CONTENTS:" ) ;
97+ println ! ( "========================" ) ;
98+
99+ let file_size = fs:: metadata ( "models/inspection_model.json" ) ?. len ( ) ;
100+ println ! ( " 📊 File size: {} bytes" , file_size) ;
101+
102+ // Show a sample of the JSON structure
103+ let content = fs:: read_to_string ( "models/inspection_model.json" ) ?;
104+ let lines: Vec < & str > = content. lines ( ) . collect ( ) ;
105+
106+ println ! ( " 📋 JSON Structure (first 30 lines):" ) ;
107+ for ( i, line) in lines. iter ( ) . enumerate ( ) . take ( 30 ) {
108+ println ! ( " {}: {}" , i + 1 , line) ;
109+ }
110+
111+ if lines. len ( ) > 30 {
112+ println ! ( " ... ({} more lines)" , lines. len( ) - 30 ) ;
113+ }
114+ println ! ( ) ;
115+
116+ Ok ( ( ) )
117+ }
118+
119+ fn explain_llm_context ( ) {
120+ println ! ( "🤖 FOR LARGE LANGUAGE MODELS (LLMs):" ) ;
121+ println ! ( "=====================================" ) ;
122+ println ! ( "If you trained an LSTM-based LLM, the model would store:" ) ;
123+ println ! ( ) ;
124+
125+ println ! ( "📚 LEARNED LANGUAGE PATTERNS:" ) ;
126+ println ! ( " • Word relationships and dependencies" ) ;
127+ println ! ( " • Grammar and syntax patterns" ) ;
128+ println ! ( " • Semantic associations between concepts" ) ;
129+ println ! ( " • Long-term dependencies in text" ) ;
130+ println ! ( ) ;
131+
132+ println ! ( "🧠 HOW PATTERNS ARE ENCODED:" ) ;
133+ println ! ( " • w_ih weights: How input words influence gates" ) ;
134+ println ! ( " - Input gate: Which words trigger memory updates" ) ;
135+ println ! ( " - Forget gate: Which contexts cause forgetting" ) ;
136+ println ! ( " - Cell gate: What new information words contribute" ) ;
137+ println ! ( " - Output gate: What words trigger specific outputs" ) ;
138+ println ! ( ) ;
139+
140+ println ! ( " • w_hh weights: How previous context influences current processing" ) ;
141+ println ! ( " - Encodes how past words affect current decisions" ) ;
142+ println ! ( " - Captures sequential dependencies and patterns" ) ;
143+ println ! ( " - Stores grammatical and syntactic relationships" ) ;
144+ println ! ( ) ;
145+
146+ println ! ( " • Biases: Default tendencies and adjustments" ) ;
147+ println ! ( " - Language-specific biases (e.g., word order preferences)" ) ;
148+ println ! ( " - Default gate behaviors for the language" ) ;
149+ println ! ( ) ;
150+
151+ println ! ( "📖 EXAMPLE: Training on 'The cat sat on the mat':" ) ;
152+ println ! ( " • Weights learn that 'The' often precedes nouns" ) ;
153+ println ! ( " • 'cat' + 'sat' pattern gets encoded in w_hh" ) ;
154+ println ! ( " • 'on the' creates strong forward dependency" ) ;
155+ println ! ( " • Sentence boundaries trigger memory resets" ) ;
156+ println ! ( ) ;
157+
158+ println ! ( "💾 METADATA ALSO STORED:" ) ;
159+ println ! ( " • Training information (epochs, loss, date)" ) ;
160+ println ! ( " • Architecture details (vocabulary size, embedding dim)" ) ;
161+ println ! ( " • Model version and description" ) ;
162+ println ! ( " • Performance metrics" ) ;
163+ println ! ( ) ;
164+ }
165+
166+ fn calculate_parameter_count ( network : & LSTMNetwork ) {
167+ println ! ( "🔢 TOTAL PARAMETER COUNT:" ) ;
168+ println ! ( "=========================" ) ;
169+
170+ let mut total_params = 0 ;
171+
172+ for ( layer_idx, cell) in network. get_cells ( ) . iter ( ) . enumerate ( ) {
173+ let w_ih_params = cell. w_ih . len ( ) ;
174+ let w_hh_params = cell. w_hh . len ( ) ;
175+ let b_ih_params = cell. b_ih . len ( ) ;
176+ let b_hh_params = cell. b_hh . len ( ) ;
177+
178+ let layer_params = w_ih_params + w_hh_params + b_ih_params + b_hh_params;
179+ total_params += layer_params;
180+
181+ println ! ( " Layer {}: {} parameters" , layer_idx, layer_params) ;
182+ }
183+
184+ println ! ( " 🎯 Total: {} trainable parameters" , total_params) ;
185+ println ! ( " 💾 Memory: ~{:.1} KB (f64 precision)" , total_params as f64 * 8.0 / 1024.0 ) ;
186+ println ! ( ) ;
187+
188+ println ! ( "📊 COMPARISON TO MODERN LLMs:" ) ;
189+ println ! ( " • GPT-3: ~175 billion parameters" ) ;
190+ println ! ( " • This LSTM: {} parameters" , total_params) ;
191+ println ! ( " • Ratio: This model is {:.0}x smaller" , 175_000_000_000.0 / total_params as f64 ) ;
192+ println ! ( ) ;
193+
194+ println ! ( "💡 SCALING FOR LLMs:" ) ;
195+ println ! ( " For a production LSTM LLM you might use:" ) ;
196+ println ! ( " • Input size: 512-1024 (embedding dimension)" ) ;
197+ println ! ( " • Hidden size: 1024-4096 (memory capacity)" ) ;
198+ println ! ( " • Layers: 6-12 (depth for complex patterns)" ) ;
199+ println ! ( " • Vocabulary: 50,000-100,000 tokens" ) ;
200+
201+ // Calculate a realistic LLM size
202+ let llm_input = 512 ;
203+ let llm_hidden = 2048 ;
204+ let llm_layers = 8 ;
205+
206+ let llm_params_per_layer = ( llm_input * llm_hidden * 4 ) + ( llm_hidden * llm_hidden * 4 ) + ( llm_hidden * 4 * 2 ) ;
207+ let llm_total_params = llm_params_per_layer * llm_layers;
208+
209+ println ! ( " Example LSTM LLM ({} layers, {} hidden): ~{:.1}M parameters" ,
210+ llm_layers, llm_hidden, llm_total_params as f64 / 1_000_000.0 ) ;
211+ }
0 commit comments