
    S.il6                     H   d Z ddlZddlZddlmZ ddlmZ ddlZddl	Z	ddl
mZ ddlmc mZ ddlmZmZmZ ddlmZmZ ddlmZ  G d d	      Z e       Zd
 Zd ZddZddZddZ G d de      Zd Z  G d dejB                        Z"ddZ#d Z$d Z%e&dk(  r e%        yy)a?  
Prefix-to-word completion with exact-match reward.

Task:
- Input: rendered prefix of a word, e.g. "the_" or "consci_"
- Target: the full word identity

Training:
- Supervised cross-entropy warmup
- Reward fine-tuning with exact-match reward

This is closer to a masked-word completion task than next-word prediction.
    N)defaultdict)Path)Image	ImageDraw	ImageFont)Dataset
DataLoader)pad_sequencec                       e Zd ZdZdZdZdZdZdZdZ	dZ
dZd	Zd
ZdZdZdZ ej$                  ej&                  j)                         rd      Zyd      Zy)Configz./books         N      @   MbP?   ffffff?g333333?g?cudacpu)__name__
__module____qualname__book_folderimg_size	font_size	embed_dimnum_classesmin_prefix_lenmax_prefix_len
batch_sizeepochslrwarmup_epochs
cls_weightreward_weightbaseline_momentumtorchdevicer   is_available     ex04.pyr   r      sw    K HI IK NN JF	BMJMU\\EJJ$;$;$=&IF5IFr-   r   c                 D   g }t        |       }|j                         st        d|  d       t               S |j	                  d      D ]  }t        d|j
                          t        |ddd      5 }|j                         }d d d        t        j                  d	      }|j                  |D cg c]  }|j                          c}        t        |      d
k(  rt        d|  d       t               S t        dt        |       d       |S # 1 sw Y   xY wc c}w )Nu   ⚠️ Folder 'z' not found. Using sample text.z*.mdu   📖 Loading: rzutf-8ignore)encodingerrors[a-zA-Z]{2,}r   u   ⚠️ No words found in z. Using sample text.u   ✅ Extracted z words from markdown files.)r   existsprintsample_wordsglobnameopenreadrefindallextendlowerlen)folder_pathwordsfoldermd_filefcontent	extractedws           r.   load_markdown_filesrI   ;   s   E+F==?},KLM~;;v& 5w||n-.'3B 	affhG	JJ8	3Aaggi345 5zQ)+6JKL~	N3u:,&A
BCL	 	 4s   2D0D
D	c                  N    d} t        j                  d| j                               S )Na  
    intelligence artificial machine learning neural network deep
    consciousness awareness thinking reasoning planning algorithm
    data information knowledge wisdom understanding insight logic
    mathematics physics chemistry biology science research study
    r4   )r<   r=   r?   )sample_texts    r.   r7   r7   Q   s%    K ::o{'8'8':;;r-   c                    t        t              }| D ]  }||xx   dz  cc<    t        |j                         d       }|d | D cg c]  \  }}|	 }}}t	        |      D ci c]  \  }}||
 }	}}|	j                         D ci c]  \  }}||
 }
}}t        dt        |              |	|
|fS c c}}w c c}}w c c}}w )Nr   c                     | d    S )Nr   r,   )xs    r.   <lambda>z"build_vocabulary.<locals>.<lambda>`   s    adU r-   )keyu   📚 Vocabulary size: )r   intsorteditems	enumerater6   r@   )rB   max_vocab_sizeword_countswordsorted_wordsrH   _vocab_wordsidxword2idxidx2words              r.   build_vocabularyr^   [   s    c"K DQ +++-?CL!-o~!>?A1?K?+4[+ABic4c	BHB+3>>+;<idCT	<H<	"3{#3"4
56X{** @B<s   B4%B:C c                    t        j                  d||fd      }t        j                  |      }	 t	        j
                  d|      }|j                  d| |      }|d   |d	   z
  }|d
   |d   z
  }||z
  dz  }	||z
  dz  }
|j                  |	|
f| d	|       t        j                  |t        j                        dz  }d|z
  S # t        $ r> 	 t	        j
                  d|      }n## t        $ r t	        j                         }Y nw xY wY w xY w)NL   )colorz//usr/share/fonts/truetype/dejavu/DejaVuSans.ttfz	arial.ttf)r   r   )font   r   r   r   )fillrc   dtypeg     o@      ?)r   newr   Drawr   truetype	Exceptionload_defaulttextbboxtextnparrayfloat32)ro   sizer   imgdrawrc   bbox
text_widthtext_heightrN   y	img_arrays               r.   render_text_imager{   j   s   
))C$S
1C>>#D,!!"SU^_ ==D=1Da47"Jq'DG#K	
	q A		!AIIq!fdI.BJJ/%7I?!  ,	,%%k9=D 	,))+D	,,s5   C 	DC&%D&DDDDDc                 .    | d | }t        |dz   ||      S )NrY   rs   r   )r{   )rW   
prefix_lenrs   r   prefixs        r.   render_prefix_imager      s!    +:FVc\	JJr-   c                   $    e Zd ZdZddZd Zd Zy)PrefixDatasetz6Prefix-to-word dataset with exact-match target labels.c                    g | _         || _        t        |j                               }|D cg c]  }||v st	        |      dkD  s| }}t	        |      |kD  r|d | }|D ]  }t        t        j                  t	        |      dz
        }t        t        j                  |      }	t        j                  |	|      }
|d |
 }	 t        ||
t        j                  t        j                        }| j                   j%                  |||   ||d        t'        dt	        | j                          d       y c c}w # t        $ rF t        j                   t        j                  t        j                  ft        j"                        }Y w xY w)Nr   r}   rf   )image
target_idxr   rW   u   🖼️ Prefix dataset: z samples)samplesr\   setkeysr@   mincfgr!   r    randomrandintr   r   r   rl   rp   zerosrr   appendr6   )selfrB   r\   max_samples	vocab_setrH   valid_wordsrW   
max_prefix
min_prefixr~   r   rt   s                r.   __init__zPrefixDataset.__init__   sU    (	"'IQ1	>c!fqjqII{k)%l{3K 	DS//TQ?JS//<J
J?J+:&FO)$
Y\YfYfg LL "*4.$ 		( 	(T\\):(;8DE3 J  Ohhcll;2::NOs#   	D2D2D2?+D77AFFc                 ,    t        | j                        S N)r@   r   )r   s    r.   __len__zPrefixDataset.__len__   s    4<<  r-   c                     | j                   |   }t        j                  |d         j                  d      t        j                  |d   g      |d   |d   fS )Nr   r   r   r   rW   )r   r)   FloatTensor	unsqueeze
LongTensor)r   r[   samples      r.   __getitem__zPrefixDataset.__getitem__   s\    c"fWo.88;f\23486N	
 	
r-   N)iP  )r   r   r   __doc__r   r   r   r,   r-   r.   r   r      s    @F@!
r-   r   c                     t        |  \  }}}}t        j                  |d      }t        j                  |d      }||t        |      t        |      fS )Nr   dim)zipr)   stacklist)batchimagesr   prefix_text	full_words        r.   collate_prefix_batchr      sL    14e.FJY[[Q'FZQ/J:tK0$y/AAr-   c                   *     e Zd ZdZd fd	Zd Z xZS )PrefixWordMLPz2Visual encoder + classifier for prefix completion.c                 r   t         |           t        j                  t        j                  dddd      t        j
                         t        j                  d      t        j                  dddd      t        j
                         t        j                  d      t        j                  dddd      t        j
                         t        j                  d      	      | _        t        j                         | _	        t        j                  d	|      | _        t        j                  ||      | _        y )
Nr       r   )kernel_sizepaddingrd   )r   r   r   i  )superr   nn
SequentialConv2dReLU	MaxPool2dfeaturesFlattenflattenLinear	embedding
classifier)r   r   r   	__class__s      r.   r   zPrefixWordMLP.__init__   s    IIaA6GGILLQ'IIb"!Q7GGILLQ'IIb#1a8GGILLQ'

 zz|;	:))I{;r-   c                     | j                  |      }| j                  |      }| j                  |      }| j                  |      }||fS r   )r   r   r   r   )r   rN   embedlogitss       r.   forwardzPrefixWordMLP.forward   sC    MM!LLOq!'u}r-   )r   )r   r   r   r   r   r   __classcell__)r   s   @r.   r   r      s    <<"r-   r   c                 	   t         j                  j                  | j                         |      }t	        j
                         }d}| j                  t        j                         t        |      D ]h  }| j                          d}	d}
d}d}d}|D ][  \  }}}}|j                  t        j                        }|j                  d      j                  t        j                        }|j                           | |      \  }} |||      }t        j                  |d      }t         j                  j!                  |      }|j#                         }||k(  j%                         }|j'                         j)                         }|t        j*                  k  r|}nt        j,                  |z  dt        j,                  z
  |z  z   }||z
  }|j/                         |j1                  |      z  j'                          }t        j2                  |z  t        j4                  |z  z   }|j7                          t         j                  j8                  j;                  | j                         d       |j=                          |j?                  d      }|||k(  jA                         j)                         z  }||jC                  d      z  }|	|j)                         z  }	|
|j)                         z  }
||z  }^ d	|z  |z  }|	tE        tG        |      d      z  }|
tE        tG        |      d      z  }|tE        tG        |      d      z  }| jI                          d} d}!d}"d}#t        jJ                         5  |D ]  \  }}}}|j                  t        j                        }|j                  d      j                  t        j                        } | |      \  }} |||      }|j?                  d      }| |j)                         z  } |!||k(  jA                         j)                         z  }!|"|jC                  d      z  }"|#||k(  j%                         j'                         j)                         z  }# 	 d d d        d	|!z  |"z  }$| tE        tG        |      d      z  }%|#tE        tG        |      d      z  }&tM        d
|dz    d| d|dd|dd|dd|dd|%dd|$dd|&d       k | S # 1 sw Y   vxY w)N)r$           r   r   r   rh   )max_norm      Y@zEpoch /z	 | Loss: .4fz | CE: z
 | Train: .2fz% | Reward: z.3fz | Val Loss:  | Val: z% | Val Reward: )'r)   optimAdam
parametersr   CrossEntropyLosstor   r*   rangetrainsqueeze	zero_gradFsoftmaxdistributionsCategoricalr   floatmeanitemr%   r(   detachlog_probr&   r'   backwardutilsclip_grad_norm_stepargmaxsumrs   maxr@   evalno_gradr6   )'modeltrain_loader
val_loaderr#   r$   	optimizer	criterionbaselineepoch
train_losstrain_cetrain_rewardtrain_correcttrain_totalr   r   rY   r   ce_lossprobsdistsampledrewardreward_meanloss	advantagerl_losspreds	train_accavg_lossavg_ce
avg_rewardval_lossval_correct	val_total
val_rewardval_accavg_val_lossavg_val_rewards'                                          r.   train_modelr     s     !1!1!3 ;I##%IH	HHSZZv L

(4 	($FJ1YYszz*F#++B/223::>J!fIFA
3GIIf!,E&&2259DkkmG+224F ++-,,.Ks(((008;sSEZEZ?Z^i>ii"X-	%,,.w1GGMMOO~~/#2C2Cg2MMMMOHHNN**5+;+;+=*LNNMMaM(Eez1668==??M:??1--K$))+%J&HK'L?	(B M)K7	C$5q 99CL 1155!CL(91$==


	
]]_ 	J,6 J(
Aq3::.'//366szzB
!&M	 4!,DIIK' 388:??AAZ__Q//	u
299;@@BGGII
J	J +%	1#c*oq"99#c#j/1&==U1WIQvh 'cN'& 6_LC0@ A%c*(73- @)#.	0	
ML
\ L5	J 	Js   +C=SS'	c                    | j                          t        j                         }d}d}d}g }t        j                         5  |D ]  \  }}	}
}|j                  t        j                        }|	j                  d      j                  t        j                        }	 | |      \  }} |||	      }|j                  d      }||j                         z  }|||	k(  j                         j                         z  }||	j                  d      z  }|j                  ||	k(  j                         j                                 	 d d d        d|z  |z  }|t!        t#        |      d      z  }|rt        t%        j&                  |            nd}t)        d       t)        d       t)        d	       t)        d
|d       t)        d|dd| d| d       t)        d|d       t)        d       d}t        j                         5  |D ]  \  }}	}
} | |j                  t        j                              \  }}|j                  d      j+                         }t-        t/        dt#        |                  D ]\  }|j1                  ||   j                         d      }||   }|
|   }||k(  rdnd}t)        d| d| d| d| d	       |dz  }|dk\  s\ n |dk\  s n d d d        t)        d	       |S # 1 sw Y   xY w# 1 sw Y   #xY w)Nr   r   r   r   r   r   z=
============================================================u#   📊 PREFIX COMPLETION TEST RESULTS<============================================================zTest Loss: r   zExact-Match Accuracy / Reward: r   z% (r   )zAverage Reward: u   
🔍 Sample Predictions:r   ?u   ✅u   ❌z  z 'z_' -> True: 'z' | Pred: ''   )r   r   r   r)   r   r   r   r*   r   r   r   r   rs   r>   r   tolistr   r@   rp   r   r6   r   r   r   get)r   test_loaderr]   r   	test_losstest_correct
test_totalexact_rewardsr   r   r   r   r   rY   r   r   test_accr   r   showni	pred_word	true_wordr   statuss                            r.   
test_modelr  4  s   	JJL##%IILJM	 I:E 	I6FJYYYszz*F#++B/223::>JfIFAVZ0DMMaM(E$IUj0557<<>>L*//!,,J  %:"5!<!<!>!E!E!GH	II |#j0H3s;/33H2?rww}-.SJ	/	
/0	(O	K~
&'	+HS>\N!J<WX
YZ	Z,
-.	
&'E	 :E 	6FJYfii

34IFAMMaM(,,.E3q#i.12 $LLq#>	%aL	$Q"+y"8e6("VHM)KPY{Z[\]
A: z	" 
(OO[I I6 s&   C;K+=CK8
K8K8+K58Lc            
      F   t        d       t        d       t        d       t        t        j                        } t        d       t	        | d      \  }}}t        |      t        _        t        dt        j                   d       t        | |d	
      }t        d       t        |      }t        d|z        }t        d|z        }||z
  |z
  }t        j                  j                  j                  ||||g      \  }	}
}t        |	t        j                  dt               }t        |
t        j                  dt               }t        |t        j                  dt               }t        dt        |	       dt        |
       dt        |              t        d       t#        t        j                  t        j$                        }t        |       t        d       t'        |||t        j(                  t        j*                        }t        d       t-        |||      }t        j.                  |j1                         ||t        j$                  t        j                  t        j2                  t        j                  ddd       t        d       t        d|dd       y ) Nu0   🧠 Prefix Word Completion (Exact-Match Reward)r
  u'   
📂 Step 1: Loading markdown files...u$   
📚 Step 2: Building vocabulary...i  )rU   u9   
🖼️ Step 3: Creating prefix dataset (max_prefix_len=z)...i@  )r   u   
📊 Step 4: Splitting data...r   g333333?T)r"   shuffle
collate_fnFz	  Train: r   z	 | Test: u"   
🏗️ Step 5: Building model...)r   r   u1   
🚀 Step 6: Training prefix completion model...)r#   r$   u   
🧪 Step 7: Testing...)r   r   r    r!   )model_state_dictr\   r]   configzprefix_reward_completion.ptu2   
💾 Model saved to 'prefix_reward_completion.pt'zFinal Test Accuracy: r   %)r6   rI   r   r   r^   r@   r   r!   r   rQ   r)   r   datarandom_splitr	   r"   r   r   r   r  r#   r$   r  save
state_dictr    )rB   r\   r]   rZ   datasettotal
train_sizeval_size	test_sizetrain_datasetval_datasettest_datasetr   r   r  r   r  s                    r.   mainr/  m  s+   	
<=	(O	
450E	
12&6uT&R#Hh+&CO	FsGYGYFZZ^
_`E8?G	
,-LES5[!J4%< H
"X-I/4{{/?/?/L/L*h	20,M; #..$K_L J^J K_K 
Ic-()#k2B1C9SQ]M^L_
`a	
/0cooOE	%L	
>?|Z

svvVE	
%&%h7H	JJ % 0 0 2   ]]""%"4"4"%"4"4		
	
 	& 

?@	!(3q
12r-   __main__)i  )r   r   )r   r   )'r   r<   r   collectionsr   pathlibr   numpyrp   r)   torch.nnr   torch.nn.functional
functionalr   PILr   r   r   torch.utils.datar   r	   torch.nn.utils.rnnr
   r   r   rI   r7   r^   r{   r   r   r   Moduler   r  r  r/  r   r,   r-   r.   <module>r;     s    
  #       + + 0 +J J6 h,<+2K-
G -
`BBII 8Up6r>3B zF r-   