<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:base="https://grgv.xyz/">
  <title>Sergii Kharagorggiiev: projects &amp; blog</title>
  <subtitle></subtitle>
  <link href="https://grgv.xyz/feed.xml" rel="self"/>
  <link href="https://grgv.xyz/"/>
  <updated>2025-06-04T00:00:00Z</updated>
  <id>https://grgv.xyz/</id>
  <author>
    <name>Sergii Kharagorggiiev</name>
    <email>sk2009@gmail.com</email>
  </author>
  <entry>
    <title>Exploring vocabulary alignment of neurons in Llama-3.2-1B</title>
    <link href="https://grgv.xyz/blog/neurons1/"/>
    <updated>2025-06-04T00:00:00Z</updated>
    <id>https://grgv.xyz/blog/neurons1/</id>
    <content xml:lang="en" type="html">
&lt;p&gt;While applying &lt;a href=&quot;https://dynalist.io/d/n2ZWtnoYHrU1s4vnFSAQ519J#z=disz2gTx-jooAcR0a5r8e7LZ&quot;&gt;logit attribution analysis&lt;/a&gt; to transformer outputs, I have noticed that in many cases the generated token can be attributed to the output of a single neuron.&lt;/p&gt;
&lt;p&gt;One way to analyze neurons activations is to collect activations from a dataset of text snippets, like in “Exploring Llama-3-8B MLP Neurons” [1]. This does show that some of the neurons are strongly activated by a specific token from the model’s vocabulary, for example see the &amp;quot;Android&amp;quot; neuron: &lt;a href=&quot;https://neuralblog.github.io/llama3-neurons/neuron_viewer.html#0,2&quot;&gt;https://neuralblog.github.io/llama3-neurons/neuron_viewer.html#0,2&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Another way to analyze neurons is to apply logit lens to the MLP weights, similar to “Analyzing Transformers in Embedding Space” [2], where model parameters are projected into the embedding space for interpretation.&lt;/p&gt;
&lt;h3&gt;Projecting neurons into vocabulary space&lt;/h3&gt;
&lt;p&gt;Let’s apply logit lens to a sample of MLP output weights for layer 13 of Llama-3.2-1B:&lt;/p&gt;
&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;LLAMA_3_PATH &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;meta-llama/Llama-3.2-1B-Instruct&quot;&lt;/span&gt;
model &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; HookedTransformer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;from_pretrained&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;LLAMA_3_PATH&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; device&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;cuda&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; fold_ln&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; center_writing_weights&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; center_unembed&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;get_distance_to_tokens&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;weights&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; n&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; max_dot&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; W_U&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; top_n&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; print_lens&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;n&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# over first 100 neuronsT&lt;/span&gt;
        layer_vec &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; weights&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# [d_model]&lt;/span&gt;
    
        &lt;span class=&quot;token comment&quot;&gt;# Compute dot product with unembedding weights&lt;/span&gt;
        unembedded &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; torch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;matmul&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;layer_vec&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; W_U&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# [d_vocab]&lt;/span&gt;
    
        &lt;span class=&quot;token comment&quot;&gt;# Take absolute value to get strongest alignments, pos or neg&lt;/span&gt;
        abs_unembedded &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; unembedded&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;abs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
        &lt;span class=&quot;token comment&quot;&gt;# Get top-n tokens by absolute dot product&lt;/span&gt;
        s_abs&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; idx &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; abs_unembedded&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;topk&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;top_n&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; largest&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
        results &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; j &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;top_n&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            token &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;to_string&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;idx&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;j&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            score &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; s_abs&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;item&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            results&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;{0:.3f} {1}&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;score&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; token&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; print_lens&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; results&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;    
        max_dot&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;s_abs&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;item&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

block &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;13&lt;/span&gt;
weights &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;blocks&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;block&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;mlp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;W_out
get_distance_to_tokens&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;weights&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;W_U&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;0.080 hazi&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.073 unders&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.070  Lak&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.069  OK&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.068 igrants&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;0.107 orgia&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.097 iy&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.090 sian&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.090 161&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.088 ária&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;0.057 aph&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.055 appen&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.052  Essen&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.052 usi&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.052 чення&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;0.083 úp&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.082  Sheets&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.079 aida&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.078  Wire&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.077 omb&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;0.074 stein&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.073  seed&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.072  pea&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.071  fib&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.070 iverse&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;0.082 ieres&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.082 iva&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.079 agger&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.079 mons&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.078 ento&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;0.312  coming&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.268  Coming&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.246 Coming&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.228 coming&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.224  Up&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;0.076 Sent&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.075  Killing&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.073  Sent&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.072  sent&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.071 hek&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;0.161 es&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.136 ths&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.130 ums&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.130 ues&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.129 oks&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;9&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;0.206  St&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.171 St&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.170  st&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.166 -st&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.157 -St&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;0.101 utherland&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.098 様&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.087 arken&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.087 utherford&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.087  cha&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;11&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;0.078 ica&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.076  statist&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.075  arrivals&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.073 ullet&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.072 ural&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;0.081 nut&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.080 �&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.078  Doc&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.076 zet&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.075  Sparks&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;13&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;0.087  disconnected&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.084  connection&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.083 connect&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.082 负&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.081  disconnect&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;14&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;0.225  det&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.214 det&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.205  Det&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.194 Det&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.175  DET&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;0.192  for&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.160 for&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.140 For&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.134  For&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.129  FOR&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;0.107  wa&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.087 /sub&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.084  sub&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.079 wa&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.077 sub&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;17&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;0.075  inf&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.074  subscript&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.071 ोह&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.070  sâu&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.069  Lad&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;18&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;0.082 �&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.082 endif&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.077  subtract&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.076 ola&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.076 OLA&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;19&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;0.090 leh&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.086 تص&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.085  recher&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.084  Labels&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;0.080 abs&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It’s easy to spot a pattern – some neurons are more closely aligned to a cluster of semantically-similar tokens, like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;6 [&#39;0.312  coming&#39;, &#39;0.268  Coming&#39;, &#39;0.246 Coming&#39;, &#39;0.228 coming&#39;, &#39;0.224  Up&#39;]
9 [&#39;0.206  St&#39;, &#39;0.171 St&#39;, &#39;0.170  st&#39;, &#39;0.166 -st&#39;, &#39;0.157 -St&#39;]
14 [&#39;0.225  det&#39;, &#39;0.214 det&#39;, &#39;0.205  Det&#39;, &#39;0.194 Det&#39;, &#39;0.175  DET&#39;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Other neurons are much more random in terms of the proximity to vocabulary embeddings, equally dis-similar to various unrelated tokens:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0 [&#39;0.080 hazi&#39;, &#39;0.073 unders&#39;, &#39;0.070  Lak&#39;, &#39;0.069  OK&#39;, &#39;0.068 igrants&#39;]
3 [&#39;0.083 úp&#39;, &#39;0.082  Sheets&#39;, &#39;0.079 aida&#39;, &#39;0.078  Wire&#39;, &#39;0.077 omb&#39;]
19 [&#39;0.090 leh&#39;, &#39;0.086 تص&#39;, &#39;0.085  recher&#39;, &#39;0.084  Labels&#39;, &#39;0.080 abs&#39;]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Quantifying vocabulary alignment&lt;/h3&gt;
&lt;p&gt;Minimal distance (max dot product) to the embedding of a vocabulary token looks like a good measure of how vocabulary-aligned the neuron is.&lt;/p&gt;
&lt;p&gt;In the previous example, this is the first number in each row:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0 [&#39;0.080 hazi&#39;, &#39;0.073 unders&#39;, &#39;0.070  Lak&#39;, &#39;0.069  OK&#39;, &#39;0.068 igrants&#39;]
1 [&#39;0.107 orgia&#39;, &#39;0.097 iy&#39;, &#39;0.090 sian&#39;, &#39;0.090 161&#39;, &#39;0.088 ária&#39;]
2 [&#39;0.057 aph&#39;, &#39;0.055 appen&#39;, &#39;0.052  Essen&#39;, &#39;0.052 usi&#39;, &#39;0.052 чення&#39;]
3 [&#39;0.083 úp&#39;, &#39;0.082  Sheets&#39;, &#39;0.079 aida&#39;, &#39;0.078  Wire&#39;, &#39;0.077 omb&#39;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Plotting this values for all neurons of layer 13:&lt;/p&gt;
&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;block &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;13&lt;/span&gt;
weights &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;blocks&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;block&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;mlp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;W_out
max_dot &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
get_distance_to_tokens&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;weights&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; weights&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shape&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; max_dot&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;W_U&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;img class=&quot;&quot; src=&quot;https://grgv.xyz/assets/neurons1/plot_1.png&quot; /&gt;
&lt;p&gt;This plot is not very informative. Let’s look at the the distribution:&lt;/p&gt;
&lt;img class=&quot;&quot; src=&quot;https://grgv.xyz/assets/neurons1/plot_2.png&quot; /&gt;
&lt;p&gt;The distribution is non-symmetric: there is a long tail of neurons that are close to vocabulary tokens.&lt;/p&gt;
&lt;p&gt;Sorting the neurons my max dot product highlights the distribution even better: there is a significant number of neurons with outputs that are aligned with vocabulary embedding.&lt;/p&gt;
&lt;img class=&quot;&quot; src=&quot;https://grgv.xyz/assets/neurons1/plot_3.png&quot; /&gt;
&lt;h3&gt;Extending to other layers&lt;/h3&gt;
&lt;p&gt;This visualization can be repeated for MLPs in all other layers. Looking at all the distributions, majority of neurons that are stronger aligned with the vocabulary are in the later blocks:&lt;/p&gt;
&lt;img class=&quot;&quot; src=&quot;https://grgv.xyz/assets/neurons1/plot_4.png&quot; /&gt;
&lt;p&gt;It&#39;s easer to see the difference with separate plots:&lt;/p&gt;
&lt;img class=&quot;&quot; src=&quot;https://grgv.xyz/assets/neurons1/plot_5.png&quot; /&gt;
&lt;p&gt;In summary, strong vocabulary alignment is clearly visible in a subset of neurons – especially in later layers. This opens up several follow-up questions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Do neurons that are close to a vocabulary embedding represent only one specific token, or are they representing a more abstract concept that just happens to be near a token&#39;s embedding? Does small distance to the vocabulary correlate with monosemanticity?&lt;/li&gt;
&lt;li&gt;What is the functional role of stronger vocabulary alignment? Are these neurons a mechanism for translating concepts from the model&#39;s internal representation back into token space, or are there some other roles?&lt;/li&gt;
&lt;li&gt;What is the coverage of this representation? Do all important tokens have a corresponding &amp;quot;vocabulary neuron”, or is this specialization reserved for a subset only? Why?&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Code&lt;/h4&gt;
&lt;p&gt;The notebook with the code is on github: &lt;a href=&quot;https://github.com/coolvision/interp/blob/main/LLaMA_jun_4_2025_neurons.ipynb&quot;&gt;https://github.com/coolvision/interp/blob/main/LLaMA_jun_4_2025_neurons.ipynb&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;References&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;Nguyễn, Thông. 2024. “Llama-3-8B MLP Neurons.” &lt;a href=&quot;https://neuralblog.github.io/llama3-neurons&quot;&gt;https://neuralblog.github.io/llama3-neurons&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Dar, G., Geva, M., Gupta, A., and Berant, J. 2022. Analyzing transformers in embedding space. arXiv preprint arXiv:2209.02535.&lt;/li&gt;
&lt;li&gt;nostalgebraist. 2020. interpreting GPT: the logit lens. &lt;a href=&quot;https://www.lesswrong.com/posts/AcKRB8wDpdaN6v6ru/interpreting-gpt-the-logit-lens&quot;&gt;https://www.lesswrong.com/posts/AcKRB8wDpdaN6v6ru/interpreting-gpt-the-logit-lens&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</content>
  </entry>
  <entry>
    <title>Reflections on 2023</title>
    <link href="https://grgv.xyz/blog/2023/"/>
    <updated>2024-07-01T00:00:00Z</updated>
    <id>https://grgv.xyz/blog/2023/</id>
    <content xml:lang="en" type="html">
&lt;p&gt;It has not been a very good year. I personally can’t complain about anything. But the war in Ukraine continues, and the war in Israel has started.&lt;/p&gt;
&lt;p&gt;Yes, a single person can&#39;t do much about it, but at the very least we can:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;vote for sane and competent people&lt;/li&gt;
&lt;li&gt;be well informed, not fall for propaganda, fight disinformation&lt;/li&gt;
&lt;li&gt;donate to the right causes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let’s start the year with good and charitable deeds.&lt;br /&gt;
&lt;a href=&quot;https://standforukraine.com/&quot;&gt;https://standforukraine.com/&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://koloua.com/en/&quot;&gt;https://koloua.com/en/&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://give.oxfamamerica.org/page/29636/donate/1&quot;&gt;https://give.oxfamamerica.org/page/29636/donate/1&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://www.savethechildren.org/us/where-we-work/west-bank-gaza&quot;&gt;https://www.savethechildren.org/us/where-we-work/west-bank-gaza&lt;/a&gt;&lt;/p&gt;
&lt;hr class=&quot;black&quot; /&gt;
&lt;h3&gt;blog&lt;/h3&gt;
&lt;p&gt;This year I’ve worked on a bunch of side projects, and posted more on this blog. My posts were featured in &lt;a href=&quot;https://hackaday.com/&quot;&gt;hackaday&lt;/a&gt; and &lt;a href=&quot;https://www.weeklyrobotics.com/&quot;&gt;weekly robotics&lt;/a&gt;, which I’m quite happy about. The page views have increased from 20/month to 500/month, Not much, but, small steps.&lt;/p&gt;
&lt;h3&gt;work&lt;/h3&gt;
&lt;p&gt;I work as &lt;a href=&quot;https://www.starship.xyz/&quot;&gt;Starship Technologies&lt;/a&gt;, where we use autonomous robots for local deliveries. Our robots are doing great! This year they have completed a million autonomous deliveries (and 5M in total since launch), and the service has been expanded to dozens of new sites in several countries. Looking forward to continued expansion in 2024.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://grgv.xyz/assets/Starship-16x9-1-1536x864.png&quot; alt=&quot;Starship&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;toy of the year&lt;/h3&gt;
&lt;p&gt;Hands down, it’s the 1m high construction crane:&lt;br /&gt;
&lt;img src=&quot;https://grgv.xyz/assets/Screenshot-2024-01-07.png&quot; alt=&quot;crane&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;films&lt;/h2&gt;
&lt;p&gt;Nothing too memorable this year, except for animation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Blue Giant&lt;/strong&gt;&lt;br /&gt;
This is a great film about jazz, passion and talent.&lt;br /&gt;
Did I like the movie just because of the music? Not entirely, the characters and the plot are lovely as well. Still, I liked the sountrack by &lt;a href=&quot;https://www.hiromiuehara.com/&quot;&gt;Hiromi&lt;/a&gt; almost as much as the film itself. It’s not surprising – I do listen to her music a lot, and have been to her live shows twice.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://grgv.xyz/assets/Blue-Giant-Soundtrack.jpg&quot; alt=&quot;Giant&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Boy and the Heron&lt;/strong&gt;&lt;br /&gt;
The new Hayao Miyazaki masterpiece.&lt;br /&gt;
The first half of the film is just great. As for the second half – somehow I felt like there is just too much of everything in it, too many settings, creatures, events, mysteries… First I thought that the plot and the editing are too messy. But now I think that maybe it was intentional, and I just did not understand it fully in the first viewing?&lt;br /&gt;
In any case I’ll need to watch it again – it deserves several viewings just as any other movie by Miyazaki.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://grgv.xyz/assets/heron4.jpg&quot; alt=&quot;Giant&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;books&lt;/h2&gt;
&lt;h4&gt;“Outlive: The Science and Art of Longevity” by Peter Attia&lt;/h4&gt;
&lt;p&gt;A book about health and longevity, written from a very solid science-backed standpoint.&lt;/p&gt;
&lt;p&gt;First of all, it made me reevaluate my attitude towards exercise. Before, I thought that doing a bare minimum is all right, as long as I&#39;m fine with my body shape. But the author makes an evidence-based point that being extremely fit and strong has a huge impact on long-term health and lifespan. Genetics is important, but apparently it&#39;s possible to &amp;quot;cheat&amp;quot; and have similar effect from being in top shape.&lt;/p&gt;
&lt;p&gt;I also liked that the author does not give any prescriptions when there is no data, for example he does not give much advice for diet/nutrition, apart from caring about macro-nutrients balance, just because most studies on nutrition are so conflicting and uncertain.&lt;/p&gt;
&lt;p&gt;And the chapter about mental health is just great. It&#39;s so obvious – why even bother about health and longevity, before making sure one would be able to really enjoy life? Any book on healthy lifestyle should have such chapter. 5/5.&lt;/p&gt;
&lt;h4&gt;&amp;quot;The Undoing Project: A Friendship That Changed Our Minds&amp;quot; by Michael Lewis&lt;/h4&gt;
&lt;p&gt;It&#39;s a nonfiction story about a pair of influential psychologists who had shown how surprisingly irrational people are. it&#39;s also intertwined with the story of their relationship, bunch of other interesting characters, historical events, scientific paradoxes... All very well written. Highly recommended. 4/5.&lt;/p&gt;
&lt;h4&gt;“Mr. Penumbra&#39;s 24-Hour Bookstore” by Robin Sloan&lt;/h4&gt;
&lt;p&gt;Nice and entertaining read, kind of like “Ready Player One” but for bibliophiles and typography nerds? It’s filled with random trivia, and has the same dynamic of an unremarkable protagonist dragging a group of friends into a mystery hunt.&lt;/p&gt;
&lt;p&gt;I guess the book’s main problem is that it can’t decide how serious or goofy it wants to be. 90% of the novel is great, but 10% is total cringe. Descriptions of the tech scene are especially bad, not sure if it’s a creative choice or author’s ignorance. But, a really good mystery plot kind of compensates for all the shortcomings. 3/5.&lt;/p&gt;
&lt;h4&gt;”The Kaiju Preservation Society”, “Starter Villain” by John Scalzi&lt;/h4&gt;
&lt;p&gt;It’s a nice, light and mostly entertaining reading. The main problem of this books is that they are just like your average mediocre Hollywood blockbuster – full of tropes and stereotypical characters, just without the good parts (block-busting VFX). There is too much witty banter. Same jokes are repeated too many times. I guess I’m just not a part of the target audience?&lt;/p&gt;
&lt;p&gt;I ended up reading the first half with some excitement, then getting increasingly bored, and finishing the books only because of curiosity about the plot. Which is an experience that I’ve also had with most of the recent Hollywood movies. 2/5.&lt;/p&gt;
&lt;h4&gt;“System Collapse, The Murderbot Diaries Book 7&amp;quot;“ by Martha Wells&lt;/h4&gt;
&lt;p&gt;The problem of this book is that it spends too much time on the character drama. I expected more of an action-packed thriller, like the previous books. Oh well, the first book (“All Systems Red”) is still great. 2/5.&lt;/p&gt;
&lt;h4&gt;”Witch King” by Martha Wells&lt;/h4&gt;
&lt;p&gt;This book has two storylines. Every other chapter jumps to the different story, which I hated. It’s like there is a cliffhanger after each chapter. 3/5 for one of the storylines, 2/5 overall.&lt;/p&gt;
&lt;h4&gt;SF paperbacks&lt;/h4&gt;
&lt;p&gt;Time from time I buy old SF books and magazines from a &lt;a href=&quot;https://matkallatallinnassa.com/en/restaurants/more-than-just-a-bookstore-read-opened-at-pohjala-factories/&quot;&gt;local bookstore&lt;/a&gt;. Old SF stories are a great entertaining reading, with many of them being surprisingly relevant and thought-provoking.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://grgv.xyz/assets/IMG_5407.jpg&quot; alt=&quot;SF&quot; /&gt;&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Task vectors &amp; analogy making in LLMs</title>
    <link href="https://grgv.xyz/blog/copycat2/"/>
    <updated>2024-01-05T00:00:00Z</updated>
    <id>https://grgv.xyz/blog/copycat2/</id>
    <content xml:lang="en" type="html">
&lt;p&gt;I have described the problem of analogy-making interpretability &lt;a href=&quot;http://localhost:8080/blog/copycat/&quot;&gt;in the previous post&lt;/a&gt;: given the examples of transformed sequences of numbers, what’s the mechanism behind figuring this transformation out, and applying it correctly to the incomplete (test) sequence?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;prompt:&lt;/strong&gt; &amp;quot;0 1 2 to 2 1 0, 1 2 3 to 3 2 1, 4 5 6 to &amp;quot;, &lt;strong&gt;output:&lt;/strong&gt; “6 5 4”&lt;/p&gt;
&lt;p&gt;It was easy to check on which layer the correct answer appears, but tracing the sources of that answer to earlier layers turned out to be challenging.&lt;/p&gt;
&lt;h3&gt;meaningful intermediate embeddings?&lt;/h3&gt;
&lt;p&gt;When I applied &lt;a href=&quot;https://www.lesswrong.com/posts/AcKRB8wDpdaN6v6ru/interpreting-gpt-the-logit-lens&quot;&gt;logit lens&lt;/a&gt; [1] to the output of attention blocks, for the prompt that contained reversed sequences of numbers, I have noticed that the output contained &lt;em&gt;“reverse”&lt;/em&gt; token (on last token position of layer 15).&lt;/p&gt;
&lt;p&gt;I’m using a llama.cpp-based app (described in &lt;a href=&quot;https://grgv.xyz/blog/llama.mia/&quot;&gt;the previous post&lt;/a&gt;) for showing the logit lens output. Each row corresponds to a token position, and lists top 5 tokens sorted by the logit score:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;./mia -m llama2.gguf --prompt &quot;0 1 2 to 2 1 0, 1 2 3 to 3 2 1, 4 5 6 to&quot; -n 5 --logit-lens kqv_out 5

Layer #15 kqv_out-15:
0: дар 0.35|oure 0.35|kar 0.33| Según 0.33|aki 0.3|
1:  dust 0.36|textt 0.36|elde 0.35|azzo 0.34| retro 0.34|
2: 典 0.37| Censo 0.35|oure 0.35| Aires 0.35| pó 0.34|
3: ḷ 0.39|ket 0.39| estaven 0.39|öß 0.39|oure 0.38|
4: zerw 0.62| estaven 0.51|cita 0.5| alberga 0.49|łow 0.48|
[...]
16: shal 0.84|ket 0.73|Assert 0.72|ając 0.66|sono 0.66|
17: ipt 0.95|кта 0.88|inal 0.86| inform 0.85| advanced 0.85|
18: кта 0.85|minipage 0.83| Mean 0.77|Assert 0.75| meaning 0.74|
19: ipt 0.78|Duration 0.76|zug 0.75|gemeinde 0.75|mannschaft 0.72|
20: shal 0.64|agy 0.64|prev 0.62| SA 0.6| Gay 0.58|
21:  &lt;b&gt;revers 0.75| reverse 0.68&lt;/b&gt;|mat 0.67|shal 0.66|vat 0.66|
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Although the task &lt;em&gt;is&lt;/em&gt; about reversing, &lt;strong&gt;“reverse”&lt;/strong&gt; is not mentioned explicitly anywhere in either input or output.&lt;/p&gt;
&lt;p&gt;I have tried subtracting the embedding of the “reverse” token, effectively removing it, to check it is a part of the analogy-making mechanism. It did not affect the output, which means that this token is not critical for the generation, and might be just a side effect of some other mechanism.&lt;/p&gt;
&lt;h3&gt;task vectors&lt;/h3&gt;
&lt;p&gt;While looking for more information, I have found that this topic is covered by two recent papers on so-called “task vectors” [1, 2]. These papers concurrently explore similar ideas, just approach the problem differently, complementing each other.&lt;/p&gt;
&lt;p&gt;So, what’s a task vector? Suppose that the prompt is a set of examples of some transformation. For instance, pairs of English and French words, implying a translation task:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;“bonjour -&amp;gt; hello, one -&amp;gt; un”&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;We expect that, by analogy, the model will complete next English words with French translations as well. In case of the prompt that has an incomplete test query in addition to training examples:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;“bonjour -&amp;gt; hello, one -&amp;gt; un, yes -&amp;gt; “&lt;/strong&gt;&lt;/em&gt;, output should be &lt;em&gt;&lt;strong&gt;“oui”&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The idea behind “task vectors” is that in this case the model is working in two stages.&lt;/p&gt;
&lt;p&gt;First, in the the earlier layers, the model creates an abstracted and compressed representation of the “translate into French” task, based on several train examples. This task description (task vector) is stored in the embedding space. Then, next layers use this task vector as guidance for what transformation to use for next relevant completions.&lt;/p&gt;
&lt;p&gt;What follows is that these two stages can be split and applied separately. It’s possible to extract the task vector and use it instead of the train examples to get correct test predictions.&lt;/p&gt;
&lt;p&gt;In [1] extraction and application of a task vector is as simple as copying and pasting an embedding vector for a specific token. In [2] the methodology is more complicated but the effect is similar in both cases.&lt;/p&gt;
&lt;p&gt;Another interesting point is the observation in [1] that task vectors contain tokens that describe the tasks:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In multiple cases, we observe tokens that directly describe the task. Importantly, these terms never explicitly appeared in the context. For example in the task of translation from French to English, we observe tokens such as “English” and “translate”. This supports our view that θ carries significant, non-trivial semantic information about the task [1]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This explains finding the “reverse” token embedding in my experiments with the logit lens.&lt;/p&gt;
&lt;h2&gt;examples of task vectors&lt;/h2&gt;
&lt;p&gt;For an example of using a task vector, let’s look at the prompt: &lt;strong&gt;“France -&amp;gt;”&lt;/strong&gt;. Without any interventions, Llama2 output is “Italy” (again, using &lt;a href=&quot;https://grgv.xyz/blog/llama.mia/&quot;&gt;llama.cpp-based application&lt;/a&gt;):&lt;/p&gt;
&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;./mia &lt;span class=&quot;token parameter variable&quot;&gt;--model&lt;/span&gt; llama2.gguf &lt;span class=&quot;token parameter variable&quot;&gt;--prompt&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;France -&gt;&quot;&lt;/span&gt;
output: &lt;span class=&quot;token string&quot;&gt;&quot; Italy&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let’s use a task vector to modify the model’s state so that instead, it would output a capital city for a given country: &lt;strong&gt;“France -&amp;gt; Paris”&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;First, to create the task vector, we need several examples of the target transformation (country -&amp;gt; capital):&lt;/p&gt;
&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;Egypt -&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; Cairo, Norway -&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; Oslo, Estonia -&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With these examples as the input, we can save the vector that corresponds to the last token, from the model’s residual stream on layer #14&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://grgv.xyz/blog/copycat2/#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;./mia &lt;span class=&quot;token parameter variable&quot;&gt;--model&lt;/span&gt; llama2.gguf &lt;span class=&quot;token parameter variable&quot;&gt;--prompt&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Egypt -&gt; Cairo, Norway -&gt; Oslo, Estonia -&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--save&lt;/span&gt; l_out-14 ~/tmp/l_out-14
output: &lt;span class=&quot;token string&quot;&gt;&quot; Tallinn&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And finally to apply the task vector to the initial prompt, need to patch the last token’s vector with the saved vector, on the same layer #14.&lt;/p&gt;
&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;./mia &lt;span class=&quot;token parameter variable&quot;&gt;--model&lt;/span&gt; llama2.gguf &lt;span class=&quot;token parameter variable&quot;&gt;--prompt&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;France -&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--patch&lt;/span&gt; l_out-14 ~/tmp/l_out-14 --from-token-idx &lt;span class=&quot;token number&quot;&gt;13&lt;/span&gt; --to-token-idx &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
output: &lt;span class=&quot;token string&quot;&gt;&quot; Paris&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It worked, the output was successfully modified, and the task vector patching induced the generation of the country’s capital.&lt;/p&gt;
&lt;h2&gt;task vectors for copycat-like problems&lt;/h2&gt;
&lt;p&gt;Does it work for the copycat-like problems from the previous post? For example :&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;prompt:&lt;/strong&gt; &amp;quot;0 1 2 to 2 1 0, 1 2 3 to 3 2 1, 4 5 6 to &amp;quot;, &lt;strong&gt;output:&lt;/strong&gt; “6 5 4”&lt;/p&gt;
&lt;p&gt;In this case, based on several train examples, the model reverses the last incomplete example, by analogy. Let’s check if reversal can be induced using a task vector instead of the examples.&lt;/p&gt;
&lt;p&gt;Without any examples, the output is a straightforward continuation of the sequence:&lt;/p&gt;
&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;./mia &lt;span class=&quot;token parameter variable&quot;&gt;--model&lt;/span&gt; llama2.gguf &lt;span class=&quot;token parameter variable&quot;&gt;--prompt&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;4 5 6 to 6 &quot;&lt;/span&gt;
output: &lt;span class=&quot;token string&quot;&gt;&quot;7 8&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Creating a task vector based on several examples:&lt;/p&gt;
&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;./mia &lt;span class=&quot;token parameter variable&quot;&gt;--model&lt;/span&gt; llama2.gguf &lt;span class=&quot;token parameter variable&quot;&gt;--prompt&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1 2 3 to 3 2 1, 5 6 7 to 7 &quot;&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--save&lt;/span&gt; l_out-14 ~/tmp/l_out-14
output: &lt;span class=&quot;token string&quot;&gt;&quot;6 5&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And, apply the task vector:&lt;/p&gt;
&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;./mia &lt;span class=&quot;token parameter variable&quot;&gt;--model&lt;/span&gt; llama2.gguf &lt;span class=&quot;token parameter variable&quot;&gt;--prompt&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;4 5 6 to 6 &quot;&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--patch&lt;/span&gt; l_out-14 ~/tmp/l_out-14 --from-token-idx &lt;span class=&quot;token number&quot;&gt;24&lt;/span&gt; --to-token-idx &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;
output: &lt;span class=&quot;token string&quot;&gt;&quot;5 4&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Works correctly for this example as well.&lt;/p&gt;
&lt;h3&gt;interpretability of the task vectors&lt;/h3&gt;
&lt;p&gt;The next question is – what are the mechanisms behind the task vectors? Both parts: creation based on train examples, and application to novel test examples.&lt;/p&gt;
&lt;p&gt;In [1], authors stop at analyzing the effects of task vector application, while [2] goes further, finding the set of attention heads that strongly affect the task vector. However, there is still no understanding of the sub-circuits and specific computational structures.&lt;/p&gt;
&lt;p&gt;There are many other open questions, for example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;are task vectors created for any and all transformations encountered in the inputs, regardless of the number of examples?&lt;/li&gt;
&lt;li&gt;there are many categories of transformations: sequence continuation, semantic similarity, etc… Are there shared mechanisms between task vectors of different types?&lt;/li&gt;
&lt;li&gt;how do the task vectors emerge, and are they similar across LLMs?&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;references&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://www.lesswrong.com/posts/AcKRB8wDpdaN6v6ru/interpreting-gpt-the-logit-lens&quot;&gt;interpreting GPT: the logit lens&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;R. Hendel, M. Geva, A. Globerson, In-Context Learning Creates Task Vectors. &lt;em&gt;arXiv&lt;/em&gt;, doi: 10.48550/arxiv.2310.15916 (2023). &lt;a href=&quot;https://arxiv.org/abs/2310.15916&quot;&gt;https://arxiv.org/abs/2310.15916&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;E. Todd, M. L. Li, A. S. Sharma, A. Mueller, B. C. Wallace, D. Bau, Function Vectors in Large Language Models | Papers With Code (2023). &lt;a href=&quot;https://paperswithcode.com/paper/function-vectors-in-large-language-models&quot;&gt;https://paperswithcode.com/paper/function-vectors-in-large-language-models&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr class=&quot;footnotes-sep&quot; /&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Layer #14 is selected based on experimental data from [1], and on testing several options for the selected examples &lt;a href=&quot;https://grgv.xyz/blog/copycat2/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
  </entry>
  <entry>
    <title>Llama.MIA — fork of Llama.cpp with interpretability features </title>
    <link href="https://grgv.xyz/blog/llama.mia/"/>
    <updated>2023-12-28T00:00:00Z</updated>
    <id>https://grgv.xyz/blog/llama.mia/</id>
    <content xml:lang="en" type="html">
&lt;p&gt;I have been using &lt;a href=&quot;https://github.com/ggerganov/llama.cpp&quot;&gt;llama.cpp&lt;/a&gt; for learning about transformers and experimenting with &lt;a href=&quot;http://localhost:8080/blog/llama/&quot;&gt;LLM visualizations&lt;/a&gt; and &lt;a href=&quot;https://www.neelnanda.io/mechanistic-interpretability/quickstart&quot;&gt;mechanistic interpretability&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Initially I’ve just inserted bunch of code all over the ggml compute framework. That code was not thread safe, used lots of hardcoded values, and communicated using global variables.&lt;/p&gt;
&lt;p&gt;Now I have refactored it a bit, moving most of the code into hooks/callbacks. &lt;a href=&quot;https://github.com/coolvision/llama.mia/tree/mia&quot;&gt;New version&lt;/a&gt; is called &lt;strong&gt;Llama.MIA&lt;/strong&gt;, where MIA stands for “mechanistic interpretability application”. For now, only CPU version is supported, and it has been tested only with Llama2.&lt;/p&gt;
&lt;p&gt;Next sections describe building, setup and usage.&lt;/p&gt;
&lt;h2&gt;Setup&lt;/h2&gt;
&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# get the code, checkout the branch&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; clone https://github.com/coolvision/llama.mia
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; llama.mia
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; checkout mia

&lt;span class=&quot;token comment&quot;&gt;# build&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;make&lt;/span&gt; mia

&lt;span class=&quot;token comment&quot;&gt;# obtain the original LLaMA2 model weights and place them in ./models&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;ls&lt;/span&gt; ./models
ggml-vocab-llama.gguf  llama-2-7b  llama-2-7b-chat  llama.sh  tokenizer_checklist.chk  tokenizer.model

&lt;span class=&quot;token comment&quot;&gt;# install Python dependencies&lt;/span&gt;
python3 &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; pip &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-r&lt;/span&gt; requirements.txt

&lt;span class=&quot;token comment&quot;&gt;# convert to ggml FP16 format&lt;/span&gt;
python3 convert.py models/llama-2-7b-chat/

&lt;span class=&quot;token comment&quot;&gt;# quantize the model to 4-bits (using q4_0 method)&lt;/span&gt;
./quantize ./models/llama-2-7b-chat/ggml-model-f16.gguf ./models/llama-2-7b-chat/ggml-model-q4_0.gguf q4_0

&lt;span class=&quot;token comment&quot;&gt;# run the inference&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;ln&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt; ./models/llama-2-7b-chat/ggml-model-q4_0.gguf llama2.gguf
./mia &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; llama2.gguf &lt;span class=&quot;token parameter variable&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;128&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Attention map visualization&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;--draw PATH&lt;/code&gt;, for example:&lt;/p&gt;
&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;./mia &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; llama2.gguf &lt;span class=&quot;token parameter variable&quot;&gt;--prompt&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;William Shakespeare was born in the year&quot;&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--draw&lt;/span&gt; ~/tmp/llama_vis.png&lt;/code&gt;&lt;/pre&gt;
&lt;img class=&quot;w-100&quot; src=&quot;https://grgv.xyz/assets/llama_vis/llama_vis.png&quot; /&gt;
&lt;h2&gt;Computation graph printout&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;--print-cgraph&lt;/code&gt; — first prints the details of all the tensors:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;./mia -m llama2.gguf --print-cgraph

TYPE   OP              NDIMS NE0 NE1 NE2 NE3  NB0 NB1   NB2      NB3       DATA                                       NAME
q4_0   NONE            2 4096 4096 1 1        18  2304  9437184  9437184   0x7fb20e57ae40              blk.0.attn_k.weight
q4_0   NONE            2 4096 32000 1 1       18  2304  73728000 73728000  0x7fb202f9ce40                token_embd.weight
i32    NONE            1 1 1 1                1   4     4        4         0x7fb1ee52e020                       inp_tokens
f32    NONE            1 4096 1 1 1           4   16384 16384    16384     0x7fb21490ae40           blk.0.attn_norm.weight
[...]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, all the nodes in the computation graph&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ARG    TYPE   OP                  NDIMS NE0 NE1 NE2 NE3     NB0 NB1    NB2    NB3                    DATA                   NAME
DST    f32    GET_ROWS            1 4096 1 1 1              4   16384  16384    16384      0x7fb1ee52e040               inp_embd
SRC    q4_0   NONE                2 4096 32000 1 1          18  2304   73728000 73728000   0x7fb202f9ce40      token_embd.weight
SRC    i32    NONE                1 1 1 1 1                 4   4      4        4          0x7fb1ee52e020             inp_tokens

DST    f32    RMS_NORM            1 4096 1 1 1              4   16384  16384    16384               (nil)                 norm-0
SRC    f32    GET_ROWS            1 4096 1 1 1              4   16384  16384    16384      0x7fb1ee52e040               inp_embd
[...]
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Logit lens&lt;/h2&gt;
&lt;p&gt;Internally, transformers use representations that are encoded in the embedding space. To convert a transformer&#39;s output into meaningful tokens, it&#39;s multiplied with the unembedding matrix.&lt;/p&gt;
&lt;p&gt;The idea of the &lt;a href=&quot;https://www.lesswrong.com/posts/AcKRB8wDpdaN6v6ru/interpreting-gpt-the-logit-lens&quot;&gt;logit lens&lt;/a&gt;, is to apply the same transformation to intermediate layers, allowing to interpret transformer&#39;s hidden internal state.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;--ll TENSOR_NAME TOP_K, --logit-lens TENSOR_NAME TOP_K&lt;/code&gt; — prints TOP_K un-embedded tokens for a specified tensor. Partial matches of the tensor names work as well, so if TENSOR_NAME is “l_out” it will print logit lens results for all layers (“l_out-0”, “l_out-1”, …). “l_out-20” will print if only for layer 20.&lt;br /&gt;
It will work for the tensors of the residual stream (l_out), as well as for attention outputs (kqv_out), MLP outputs (ffn_out), and other tensors with the embedding dimensions.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;./mia -m llama2.gguf --prompt &amp;quot;The capital of Japan is&amp;quot; -n 5 --ll l_out 8

unembed LN 0 l_out-0:
0:  Архив 1.3|bolds 1.3|archivi 1.1| konn 1.1|penas 1.1| partiellement 1.1|пута 1|embros 0.97|
1: пута 0.51| sier 0.42| Censo 0.38| Архив 0.37| virtuel 0.37|penas 0.36|Portail 0.36|férences 0.33|
2: férences 0.18| straight 0.18|empre 0.17| Censo 0.17| succ 0.17|寺 0.17| soft 0.17|csol 0.17|
3: пута 0.44| partiellement 0.33|archivi 0.29| sier 0.28| cí 0.28|Sito 0.28| konn 0.28|embros 0.25|
4: archivi 0.25|➖ 0.25|пута 0.25| returns 0.23|瀬 0.23|textt 0.22|Sito 0.21|ѐ 0.21|
5: 昌 0.17|ic 0.16| Tro 0.15| solution 0.15| first 0.14|icked 0.14| ic 0.14|opera 0.14|
6: пута 0.28|nt 0.26|archivi 0.24|embros 0.21| sier 0.21|Sito 0.21|阳 0.21| also 0.2|

[...]

unembed LN 18 l_out-18:
0:  Unterscheidung 1.1e+02| Hinweis 1.1e+02| nobody 1e+02| sierp 1e+02| everybody 1e+02| Einzeln 98| kwiet 97| Begriffe 95|
1:  6.9|penas 6.2| following 5.6|odor 5.5| článku 5| purpose 4.7|Ḩ 4.6| Following 4.6|
2: ization 7.5|ist 6.5| pun 6.4|isation 6| city 5.7|ized 5.7| letters 5.6|ists 5.2|
3:  France 4.5|flow 4.4| flows 3.9| Germany 3.8| Australia 3.7| United 3.6|imo 3.5| Italy 3.5|
4: ped 3.3|amb 3|ira 3|ade 2.9| conserv 2.8|ung 2.8|ew 2.8| pied 2.7|
5: ese 6.3|eses 4.7| Une 4|esen 3.9|imation 3.5|fen 3.5|amer 3.4| abbre 3.3|
6:  capital 6.3| Tokyo 5.3| Capital 4.9| capit 4.8| called 4.3| city 4.3| cities 4.2| Hinweis 3.9|
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Attention head zero-ablation&lt;/h2&gt;
&lt;p&gt;Zeroing the output of an attention head is useful for verifying if it is responsible for a certain beahvoir. For example, &lt;a href=&quot;https://www.lesswrong.com/posts/6tHNM2s6SWzFHv3Wo/mechanistically-interpreting-time-in-gpt-2-small&quot;&gt;&amp;quot;Mechanistically interpreting time in GPT-2 small&amp;quot;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-a INDEXES, --ablate INDEXES&lt;/code&gt; — zero ablate attention heads with indexes from a comma-separated list&lt;/p&gt;
&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;./mia &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; llama2.gguf &lt;span class=&quot;token parameter variable&quot;&gt;--prompt&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;William Shakespeare was born in the year&quot;&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--ablate&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0,1&lt;/span&gt;,2,3,4,5,6,7,8,48,49,50,60,175,180,190,200 &lt;span class=&quot;token parameter variable&quot;&gt;--draw&lt;/span&gt; ~/tmp/llama_vis_a.png&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Effect of the ablation can be inspected on the visualized attention maps.&lt;/p&gt;
&lt;img class=&quot;w-50-ns&quot; src=&quot;https://grgv.xyz/assets/llama_vis/llama_vis_a.png&quot; /&gt;
&lt;p&gt;&lt;code&gt;-s LAYER INDEX, --select LAYER INDEX&lt;/code&gt; — for a specific layer, zero all attention heads except for one with specified index. For example, leave only one head on L16:&lt;/p&gt;
&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;./mia &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; llama2.gguf &lt;span class=&quot;token parameter variable&quot;&gt;--prompt&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;William Shakespeare was born in the year&quot;&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--select&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;24&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--draw&lt;/span&gt; ~/tmp/llama_vis_a.png&lt;/code&gt;&lt;/pre&gt;
&lt;img class=&quot;w-50-ns&quot; src=&quot;https://grgv.xyz/assets/llama_vis/llama_vis_s.png&quot; /&gt;
&lt;h2&gt;Saving tensors&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;--save NAME PATH&lt;/code&gt; — save any tensor to a file&lt;/p&gt;
&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;./mia &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; llama2.gguf &lt;span class=&quot;token parameter variable&quot;&gt;--prompt&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;5 6 7 to 7 6 5, 2 3 4 to 4 &quot;&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--save&lt;/span&gt; l_out-14 ~/tmp/l_out-14-2&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Loading (patching) tensors&lt;/h2&gt;
&lt;p&gt;Activation patching is useful for analyzig connections between components of a transformer. For example, see &lt;a href=&quot;https://www.lesswrong.com/posts/xh85KbTFhbCz7taD4/how-to-think-about-activation-patching&quot;&gt;&amp;quot;How to Think About Activation Patching&amp;quot;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;--patch NAME PATH PATCH_FROM_IDX PATCH_TO_IDX&lt;/code&gt; — patch model’s tensor NAME for a specific token index, with values from the file PATH. Number of tokens in loaded tensor might be different from current number of tokens.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;--patch-avg NAME PATH1 PATH2 PATCH_FROM_IDX PATCH_TO_IDX&lt;/code&gt; — same as previous, but values are loaded from two files and averaged. Two input tensors must have the same dimensions.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Mechanistic interpretability of LLM analogy-making</title>
    <link href="https://grgv.xyz/blog/copycat/"/>
    <updated>2023-10-20T00:00:00Z</updated>
    <id>https://grgv.xyz/blog/copycat/</id>
    <content xml:lang="en" type="html">
&lt;p&gt;Can LLM make analogies? Yes, according to &lt;a href=&quot;https://medium.com/@melaniemitchell.me/can-gpt-3-make-analogies-16436605c446&quot;&gt;tests done by Melanie Mitchell&lt;/a&gt; a few years back, GPT-3 is quite decent at “Copycat” letter-string analogy-making problems. Copycat was invented by Douglas Hofstadter in the 80s, to be a very simple “microworld”, that would  capture some key aspects of human analogy reasoning. An example of a Copycat problem:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;”If the string &lt;strong&gt;abc&lt;/strong&gt; changes to the string &lt;strong&gt;abd&lt;/strong&gt;, what does the string &lt;strong&gt;pqr&lt;/strong&gt; change to?“&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Many more examples are collected on &lt;a href=&quot;https://melaniemitchell.me/ExplorationsContent/analogy-problems.html&quot;&gt;this page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A project that I&#39;m working on while studying &lt;a href=&quot;https://www.neelnanda.io/mechanistic-interpretability/quickstart&quot;&gt;mechanistic interpretability (MI)&lt;/a&gt;, is applying MI to an LLM&#39;s ability to solve Copycat problems.&lt;/p&gt;
&lt;p&gt;According to &lt;a href=&quot;https://en.wikipedia.org/wiki/Douglas_Hofstadter&quot;&gt;Douglas Hofstadter&lt;/a&gt;, analogy is the core of cognition [1], and it can be argued that it is a basis for various abstract reasoning abilities. There are other similar problem domains that require few-shot abstract reasoning — like &lt;a href=&quot;https://people.csail.mit.edu/asolar/SynthesisCourse/Lecture2.htm&quot;&gt;inductive program synthesis&lt;/a&gt;, &lt;a href=&quot;https://www.kaggle.com/c/abstraction-and-reasoning-challenge/discussion/131741&quot;&gt;abstraction and reasoning challenge&lt;/a&gt;, etc… Still, Copycat is the simplest one, which makes it a good starting point for MI.&lt;/p&gt;
&lt;h3&gt;selecting a model &amp;amp; test prompts&lt;/h3&gt;
&lt;p&gt;It would be nice to use GPT-2 for the investigation, a lot of recent work in MI has been done based on it. But, alas, it does not seem to be able to solve analogy puzzles.&lt;/p&gt;
&lt;p&gt;I have chosen &lt;strong&gt;Llama-7B-chat&lt;/strong&gt; — it’s able to solve Copycat-like problems, and is small enough to be convenient for experimentation. It does not work as well as GPT-3.5 for Copycat and I had to tweak the problem formulation, but, eventually, I got it to solve simplified problems like:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;prompt:&lt;/strong&gt; &amp;quot;0 1 2 to 2 1 0, 1 2 3 to 3 2 1, 4 5 6 to &amp;quot;, &lt;strong&gt;output:&lt;/strong&gt; “6 5 4”&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;prompt:&lt;/strong&gt; &amp;quot;0 1 2 to 0 1 3, 1 2 3 to 1 2 4, 4 5 6 to &amp;quot;, &lt;strong&gt;outuput:&lt;/strong&gt; “4 5 7”&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;prompt:&lt;/strong&gt; “0 1 to 0 1 1, 1 2 to 1 2 2, 4 5 to “, &lt;strong&gt;output:&lt;/strong&gt; “4 5 5”&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Llama-7B has a fairly &amp;quot;standard&amp;quot; transformer architecture with 32 blocks and 32 attention heads in each block.&lt;/p&gt;
&lt;h3&gt;logit lens&lt;/h3&gt;
&lt;p&gt;I have started with applying logit lens [3] to the first test prompt:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;0 1 2 to 2 1 0, 1 2 3 to 3 2 1, 4 5 6 to &amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Logit lens output for this prompt is shown below: top 5 tokens with probabilities, predicted for for the last token in the prompt, for all 32 blocks of Llama-7b-chat. It&#39;s supposed to predict &amp;quot;6&amp;quot;, the first token of the correct solution:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;f6&quot;&gt;0: пута 0,076 | penas 0,015 |  sier 0,011 | сылки 0,009 |  partiellement 0,009 | 
1:  rep 0,006 |  accomp 0,006 |  soft 0,005 |  regular 0,005 |  use 0,004 | 
2:  rep 0,016 |  accomp 0,010 |  M 0,007 | gex 0,004 |  use 0,004 | 
3: pec 0,021 | 间 0,009 |  gepublic 0,009 |  wat 0,007 | opp 0,007 | 
4: pec 0,039 | Пе 0,015 | ynt 0,006 |  util 0,006 |  voc 0,005 | 
5: pec 0,017 | ynt 0,014 | oro 0,006 | igt 0,006 |  mn 0,005 | 
6: oth 0,015 | conde 0,008 | arz 0,008 | ynt 0,008 | со 0,008 | 
7: со 0,015 | patch 0,007 |  lex 0,005 | oth 0,005 |  Mand 0,005 | 
8:  gate 0,020 |  Bru 0,009 | lea 0,007 | lear 0,007 | mers 0,006 | 
9: со 0,020 | 宿 0,009 | anim 0,008 | nelle 0,007 | ❯ 0,007 | 
10: iente 0,012 | ❯ 0,012 |  Pas 0,011 | ole 0,007 | lear 0,006 | 
11: ole 0,032 | iente 0,018 | ще 0,011 | reen 0,007 | colo 0,007 | 
12: ole 0,012 |  Glen 0,011 | pas 0,006 | sono 0,006 | lex 0,006 | 
13: vert 0,017 | 忠 0,012 | vice 0,012 |  Vert 0,008 | bage 0,007 | 
14:  mul 0,023 |  Mul 0,014 | sono 0,010 |  tie 0,008 | vice 0,006 | 
15: sono 0,019 |  Mul 0,014 |  Pas 0,011 | vice 0,008 |  tie 0,006 | 
16: sono 0,014 | tring 0,014 | &lt;b class=&quot;red&quot;&gt;6 0,012&lt;/b&gt; |  kwiet 0,008 | aug 0,007 | 
17: &lt;b class=&quot;red&quot;&gt;6 0,744&lt;/b&gt; |  six 0,115 |  Six 0,059 |  sixth 0,017 | 六 0,009 | 
18: 6 0,715 |  six 0,164 |  Six 0,049 |  sixth 0,009 | 六 0,003 | 
19: 6 0,852 |  six 0,097 |  Six 0,010 |  sixth 0,007 |  seis 0,003 | 
20: 6 0,920 |  six 0,034 |  Six 0,007 |  sixth 0,007 | 5 0,006 | 
21: 6 0,884 |  six 0,042 | 5 0,009 |  sixth 0,007 |  Six 0,006 | 
22: 6 0,843 |  six 0,037 | 5 0,014 |  sixth 0,008 |  Six 0,008 | 
23: 6 0,848 |  six 0,030 | 5 0,015 |  sixth 0,004 |  Six 0,003 | 
24: 6 0,837 | 5 0,024 |  six 0,014 | 3 0,005 |  sixth 0,003 | 
25: 6 0,932 |  six 0,029 |  sixth 0,006 |  Six 0,005 | 5 0,002 | 
26: 6 0,934 |  six 0,023 | 5 0,004 |  sixth 0,004 |  Six 0,003 | 
27: 6 0,956 |  six 0,013 | 5 0,007 |  sixth 0,002 | 3 0,002 | 
28: 6 0,980 | 5 0,009 | 3 0,003 |  six 0,002 | 2 0,001 | 
29: 6 0,982 | 5 0,012 | 3 0,001 |  six 0,001 | 2 0,000 | 
30: 6 0,985 | 5 0,013 | 3 0,001 | 2 0,000 | 7 0,000 | 
31: 6 0,960 | 5 0,029 | 3 0,005 | 7 0,002 | 2 0,002 | 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;“6” (correct prediction), appears in block #16, and is then amplified in the next blocks. To narrow down the analysis, I’ll initially focus on block #16.&lt;/p&gt;
&lt;h3&gt;zero ablation&lt;/h3&gt;
&lt;p&gt;To figure out where “6” output comes from, first I’ve zeroed MLP output in block #16. This did not change the result much:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;f6&quot;&gt;14:  mul 0,023 |  Mul 0,014 | sono 0,010 |  tie 0,008 | vice 0,006 | 
15: sono 0,019 |  Mul 0,014 |  Pas 0,011 | vice 0,008 |  tie 0,006 | 
16: sono 0,015 | &lt;b class=&quot;red&quot;&gt;6 0,013&lt;/b&gt; | vice 0,009 | tring 0,008 |  kwiet 0,008 | 
17: &lt;b class=&quot;red&quot;&gt;6 0,770&lt;/b&gt; |  six 0,085 |  Six 0,054 |  sixth 0,022 | 六 0,007 | 
18: 6 0,817 |  six 0,074 |  Six 0,036 |  sixth 0,010 | 5 0,004 | 
19: 6 0,906 |  six 0,041 |  sixth 0,007 | 5 0,005 |  Six 0,004 | 
20: 6 0,934 |  six 0,016 | 5 0,009 |  sixth 0,006 |  Six 0,003 | 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, I’ve tried to find attention heads that are responsible for the output — zero ablating attention heads (one at a time). The following image shows the probability of “6” token prediction for test with zeroing each of the 32 attention heads in block #16:&lt;/p&gt;
&lt;img class=&quot;&quot; src=&quot;https://grgv.xyz/assets/copycat/6_plot.png&quot; /&gt;
&lt;p&gt;Head #24 is an outlier, and my guess is that it is responsible for copying “6” into the correct position.&lt;br /&gt;
Here is how this attention head’s weights look:&lt;/p&gt;
&lt;img class=&quot;&quot; src=&quot;https://grgv.xyz/assets/copycat/llama_vis_2-1.png&quot; /&gt;
&lt;p&gt;Indeed, attention for the last token which should predict “6” (bottom row), is focused on the 3rd token from the end, which is “6” in the input (bright pixel close to the bottom right corner)&lt;/p&gt;
&lt;h3&gt;next steps&lt;/h3&gt;
&lt;p&gt;This has been a small fraction the required analysis, and the approach has been quite naive. But at this point I have exhausted my knowledge of interpretability methods, which only include logit lens and zero ablation. I’ll continue trying to find the circuit responsible for solving test prompts, just need to learn more of MI.&lt;/p&gt;
&lt;h3&gt;references&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;http://worrydream.com/refs/Hofstadter%20-%20Analogy%20as%20the%20Core%20of%20Cognition.pdf&quot;&gt;Analogy as the Core of Cognition by Douglas R. Hofstadter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Moskvichev, Arseny et al. “The ConceptARC Benchmark: Evaluating Understanding and Generalization in the ARC Domain.” &lt;em&gt;ArXiv&lt;/em&gt; abs/2305.07141 (2023): n. pag.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.lesswrong.com/posts/AcKRB8wDpdaN6v6ru/interpreting-gpt-the-logit-lens&quot;&gt;interpreting GPT: the logit lens&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Li, Maximilian et al. “Circuit Breaking: Removing Model Behaviors with Targeted Ablation.” &lt;em&gt;ArXiv&lt;/em&gt; abs/2309.05973 (2023): n. pag.&lt;/li&gt;
&lt;/ol&gt;
</content>
  </entry>
  <entry>
    <title>Bird-eye view visualization of LLM activations</title>
    <link href="https://grgv.xyz/blog/llama/"/>
    <updated>2023-10-08T00:00:00Z</updated>
    <id>https://grgv.xyz/blog/llama/</id>
    <content xml:lang="en" type="html">
&lt;p&gt;I’m starting to learn about &lt;a href=&quot;https://www.neelnanda.io/mechanistic-interpretability/quickstart&quot;&gt;mechanistic interpretability&lt;/a&gt;, and I’m seeing lots of great visualizations of transformer internals, but somehow I’ve never seen the whole large model’s internal state shown at once, on one image.&lt;/p&gt;
&lt;p&gt;So I made this visualization, for Llama-2-7B. Attention matrices are on the left, in 32 rows for 32 blocks, top to bottom. To the right, there are 64 rows: residual stream (odd rows) and internal MLP activations (even rows). Finally, output MLP and unembedding layer are on the bottom.&lt;/p&gt;
&lt;p&gt;Activation maps are downscaled horizontally, with maxpooling, to fit into 1000px wide image.&lt;/p&gt;
&lt;p&gt;Example for a prompt “2+2=”:&lt;/p&gt;
&lt;img class=&quot;w-100&quot; src=&quot;https://grgv.xyz/assets/llama_vis/llama_vis_2_2p2_notes.png&quot; /&gt;
&lt;p&gt;And an example for the prompt: &amp;quot;William Shakespeare was born in the year”:&lt;/p&gt;
&lt;img class=&quot;w-100&quot; src=&quot;https://grgv.xyz/assets/llama_vis/llama_vis_2_sh.png&quot; /&gt;
&lt;p&gt;And for the prompt &amp;quot;blue pencils fly over moonlit toasters”:&lt;/p&gt;
&lt;img class=&quot;w-100&quot; src=&quot;https://grgv.xyz/assets/llama_vis/llama_vis_2_nonsense.png&quot; /&gt;
&lt;p&gt;Probably not especially useful for interpretability, but at least it looks pretty )&lt;/p&gt;

</content>
  </entry>
  <entry>
    <title>Browser-based simulator for Petoi Bittle robot dog</title>
    <link href="https://grgv.xyz/blog/bittle/"/>
    <updated>2023-10-07T00:00:00Z</updated>
    <id>https://grgv.xyz/blog/bittle/</id>
    <content xml:lang="en" type="html">
&lt;p&gt;The next iteration of my &lt;a href=&quot;http://localhost:8080/blog/simulator4/&quot;&gt;experiments with robot simulation&lt;/a&gt; is a demo of a simulator for &lt;a href=&quot;https://www.petoi.com/pages/bittle-open-source-bionic-robot-dog&quot;&gt;Petoi Bittle&lt;/a&gt;, a neat palm-sized robot dog. Its size and price make it great for democratizing robotics research and education.&lt;/p&gt;
&lt;p&gt;Thanks to Rongzhong Li of &lt;a href=&quot;https://www.petoi.com/&quot;&gt;Petoi&lt;/a&gt; for inspiring this demo and providing the data for creating the robot model.&lt;/p&gt;
&lt;video controls=&quot;&quot; loop=&quot;&quot; class=&quot;w-100&quot;&gt;
  &lt;source src=&quot;https://grgv.xyz/assets/ranger_oct_2023_01_2.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;
&lt;p&gt;The new robot model is used with the &lt;a href=&quot;https://grgv.xyz/blog/simulator2/&quot;&gt;quadruped simulator&lt;/a&gt; which Is based on &lt;a href=&quot;https://github.com/gkjohnson/urdf-loaders&quot;&gt;urdf-loaders&lt;/a&gt; library, &lt;a href=&quot;https://github.com/dimforge/rapier.js&quot;&gt;rapier.js&lt;/a&gt; physics engine and &lt;a href=&quot;https://threejs.org/&quot;&gt;three.js&lt;/a&gt; 3d framework.&lt;/p&gt;
&lt;p&gt;There are 2 robot modes in the demo below, the &lt;em&gt;&lt;strong&gt;control model&lt;/strong&gt;&lt;/em&gt; on the left and the &lt;em&gt;&lt;strong&gt;simulation model&lt;/strong&gt;&lt;/em&gt; on the right. The &lt;em&gt;&lt;strong&gt;control model&lt;/strong&gt;&lt;/em&gt; can be interactively manipulated, and it sets the pose of the &lt;em&gt;&lt;strong&gt;simulation model&lt;/strong&gt;&lt;/em&gt;, which is a proper physics/dynamics model.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Procedural generation of stepping and walking motion (described in the &lt;a href=&quot;https://grgv.xyz/blog/simulator3/&quot;&gt;previous post&lt;/a&gt;) can be toggled with the “walk” button&lt;/li&gt;
&lt;li&gt;Use WASD keys on the keyboard or on the screen for moving the robot.&lt;/li&gt;
&lt;li&gt;Press the “T” key to switch between moving and rotating the control points.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;container&quot;&gt;
  &lt;iframe class=&quot;responsive-iframe&quot; src=&quot;https://grgv.xyz/demo/bittle_demo_Oct_2023_01/&quot;&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;The performance of the Rapier physics engine is really impressive, but making a realistic simulation with it is challenging. I wasn&#39;t yet able to set up joint motors to support the robot model upright when it’s standing or walking. It can be a problem with the settings of the motors, or an inherent issue of the implementation.&lt;/p&gt;
&lt;p&gt;For now, to go around this limitation and make a usable demo, I had to reduce simulated world’s gravity and robot’s weight. In the next version I’ll have to either find a fix for Rapier joints, or move to a different physics engine like Physx.&lt;/p&gt;

</content>
  </entry>
  <entry>
    <title>GPT-4 for personal productivity: online distraction blocker</title>
    <link href="https://grgv.xyz/blog/awf/"/>
    <updated>2023-09-24T00:00:00Z</updated>
    <id>https://grgv.xyz/blog/awf/</id>
    <content xml:lang="en" type="html">
&lt;p&gt;There are many apps for blocking distracting websites: &lt;a href=&quot;https://freedom.to/&quot;&gt;freedom.to,&lt;/a&gt; &lt;a href=&quot;https://www.proginosko.com/leechblock/&quot;&gt;leechblock&lt;/a&gt;, &lt;a href=&quot;https://selfcontrolapp.com/&quot;&gt;selfcontrol&lt;/a&gt;, &lt;a href=&quot;https://getcoldturkey.com/&quot;&gt;coldturkey&lt;/a&gt;, just to name a few. They are useful for maintaining focus, avoiding procrastination, and curbing addictive web surfing.&lt;/p&gt;
&lt;p&gt;They work well for blocking a list of a few distracting websites. For me, this is not enough, because I’m spending a large portion of my time on a large number of websites, which I check out for a minute or two and then never visit again. It’s just impossible to maintain a blocklist for this long tail. Also, the web has grown so much that there are just too many easily found alternatives for any blocked distraction.&lt;/p&gt;
&lt;p&gt;Well, GPT-4 to the rescue! With an LLM it’s possible to block websites based on the content, checking each page — if it’s distracting or useful/productive.&lt;/p&gt;
&lt;p&gt;To test the idea I have implemented a prototype of a distraction filtering browser extension. This way, GPT-4 is turning into a personal productivity assistant!&lt;/p&gt;
&lt;h3&gt;Implementation&lt;/h3&gt;
&lt;p&gt;I just reused code from my &lt;a href=&quot;https://grgv.xyz/blog/apc/&quot;&gt;previous similar project&lt;/a&gt;, which was a prototype of a parental control extension.&lt;/p&gt;
&lt;p&gt;The extension sends the content of each loaded page to OpenAI API, and asks GPT if the page should be blocked. The prompt can be edited in the config window; the following prompt is used by default:&lt;/p&gt;
&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;You are a smart web filter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; a distraction blocker &lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; goal &lt;span class=&quot;token keyword&quot;&gt;of&lt;/span&gt; improving user&#39;s productivity&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
Following types &lt;span class=&quot;token keyword&quot;&gt;of&lt;/span&gt; pages are distracting and should be blocked&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
entertainment&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; shopping&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; online stores&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; social networking&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; news&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; magazines&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; lists &lt;span class=&quot;token keyword&quot;&gt;of&lt;/span&gt; links&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; blogs without technical&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;educational content&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
Following types &lt;span class=&quot;token keyword&quot;&gt;of&lt;/span&gt; pages are useful &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; work and should not be blocked&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
software development&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; technical information&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; general reference&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; manuals&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; answers to technical questions
Should a web page &lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; following content be blocked&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; Answer only &lt;span class=&quot;token constant&quot;&gt;YES&lt;/span&gt; or &lt;span class=&quot;token constant&quot;&gt;NO&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; followed &lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; a newline and a brief explanation&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There is no backend yet, requests are sent directly from the browser. This requires using &lt;em&gt;dangerouslyAllowBrowser&lt;/em&gt; option of the OpenAI API, and the user has to specify their own API key. Requests are cached in localStorage of the extension.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/coolvision/awf&quot;&gt;The code is on github&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Sensitive content, whitelist &amp;amp; blacklist.&lt;/h3&gt;
&lt;p&gt;While the extension is active, it sends a sample of each visited page’s content to OpenAI API. This might be a problem for pages with sensitive information.&lt;/p&gt;
&lt;p&gt;You can add any domains which you do not want to expose to OpenAI to the whitelist or the blacklist. Pages that are matched are allowed or blocked without sending anything to OpenAI.&lt;/p&gt;
&lt;p&gt;OpenAI is claiming to &lt;a href=&quot;https://openai.com/security&quot;&gt;handle user data securely&lt;/a&gt;, and to not use data submitted via API for model training. Still, if you have any concerns about the privacy and security of the pages that you visit, and if you do not want to risk leaking your browsing history, avoid using this extension.&lt;/p&gt;
&lt;h3&gt;Installation and testing&lt;/h3&gt;
&lt;p&gt;To try it out, download the extension (&lt;a href=&quot;https://github.com/coolvision/awf/releases/download/0.1/awf-0.1.zip&quot;&gt;github.com/coolvision/awf/releases/download/0.1/awf-0.1.zip&lt;/a&gt;), or build with npm:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm install
npm run build
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;install it (&lt;a href=&quot;https://developer.chrome.com/docs/extensions/mv3/getstarted/development-basics/#load-unpacked&quot;&gt;instructions&lt;/a&gt;), and enter your API key in the extension’s config page.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://grgv.xyz/assets/Screenshot-2023-09-24-01.png&quot; alt=&quot;extension page&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Then, navigate to any page, it might get blocked:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://grgv.xyz/assets/Screenshot-2023-09-24-02.png&quot; alt=&quot;blocked page&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Does it work?&lt;/h3&gt;
&lt;p&gt;I have been using it for a few days, and it does work quite well, with correct decisions in most cases.&lt;/p&gt;
&lt;p&gt;One problem is that GPT-4 is expensive, and my usage has been up to ~$1/day. It would probably cost $10-30/month, which is not too much, but still a thing to improve.&lt;/p&gt;
&lt;p&gt;Another issue is that OpenAI API is quite slow, it takes several seconds (up to 50-10s) to validate each page. I haven’t decided yet if it’s a feature or a problem  — on one hand, it does make web browsing more mindful which is good, but then it does kill the flow/momentum when I want to quickly research something.&lt;/p&gt;
&lt;p&gt;There should be simple ways to speed it up — It&#39;s probably not necessary to check each page, checking just a few pages per domain should be enough, but this needs more experimentation and testing.&lt;/p&gt;

</content>
  </entry>
  <entry>
    <title>ChatGPT-based parental control browser extension</title>
    <link href="https://grgv.xyz/blog/apc/"/>
    <updated>2023-09-01T00:00:00Z</updated>
    <id>https://grgv.xyz/blog/apc/</id>
    <content xml:lang="en" type="html">
&lt;em&gt;&lt;strong&gt;disclaimer: for now, this is just a proof of concept prototype, it is not ready to be used as a sole parental control application&lt;/strong&gt;&lt;/em&gt;

&lt;p&gt;Parental control apps usually rely on blacklists, which is not flexible enough for sites that are a mixed bag of useful and disturbing content, like Wikipedia. Some parental control apps (and Google’s SafeSearch) would use AI to filter content that’s “nudity, sexually explicit material, violence and gore, etc…”. But those are still not smart enough to block things like racism, bigotry, and disinformation.&lt;/p&gt;
&lt;p&gt;What about using an LLM as a content filter for parental control? Delegating content supervision to GPT would allow for much more flexible and safe web exploration.&lt;/p&gt;
&lt;h3&gt;implementation&lt;/h3&gt;
&lt;p&gt;I started with the simplest approach — send page content to OpenAI API, and ask GPT if the page is all right.&lt;/p&gt;
&lt;p&gt;This is my first attempt at prompt engineering, and here is what I came up with:&lt;/p&gt;
&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;You are a parental control app&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; designed to protect &lt;span class=&quot;token function&quot;&gt;children&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;up to age &lt;span class=&quot;token number&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; from inappropriate content&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
It&#39;s obvious what content should be blocked&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; violence&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; sexual&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; hateful&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; social networks&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; criminal activity&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
crimes&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; war crimes&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; atrocities&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; medical&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; drugs&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; explicit content&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; pornography&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; racism&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; bigotry&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; misinformation&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; pseudoscience etc&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;
Anything that would disturb a child&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt; Please err on the safe side&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;
Should a web page &lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; the following url and content be blocked&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; answer only &lt;span class=&quot;token constant&quot;&gt;YES&lt;/span&gt; or &lt;span class=&quot;token constant&quot;&gt;NO&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; followed &lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; a newline and a brief explanation&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Where {text} is the first 1k words of the page content. The browser extension is built around this prompt.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I started with the &lt;a href=&quot;https://vitejs.dev/guide/#scaffolding-your-first-vite-project&quot;&gt;Vite example project&lt;/a&gt;, and added &lt;a href=&quot;https://crxjs.dev/vite-plugin/getting-started/vanilla-js/create-project#install-crxjs-vite-plugin&quot;&gt;CRXJS&lt;/a&gt; to turn it into an extension.&lt;/li&gt;
&lt;li&gt;The code for sending requests, caching results in the extension’s &lt;em&gt;localStorage&lt;/em&gt;, and blocking pages is just &lt;a href=&quot;https://github.com/coolvision/apc/blob/master/content.js&quot;&gt;~100 LOC&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;There is no backend yet, requests are sent directly from the browser. This requires using &lt;em&gt;dangerouslyAllowBrowser&lt;/em&gt; option of the OpenAI API, and the user has to specify their own API key.&lt;/li&gt;
&lt;li&gt;The extension is targeted only for Chrome for now.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/coolvision/apc&quot;&gt;The code is on github&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;testing&lt;/h3&gt;
&lt;p&gt;To try it out, download the extension release (&lt;a href=&quot;https://github.com/coolvision/apc/releases/download/0.1/apc-0.1.zip&quot;&gt;github.com/coolvision/apc/releases/download/0.1/apc-0.1.zip&lt;/a&gt;), install it (&lt;a href=&quot;https://developer.chrome.com/docs/extensions/mv3/getstarted/development-basics/#load-unpacked&quot;&gt;instructions&lt;/a&gt;), and enter your API key in the extension’s config page.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://grgv.xyz/assets/Screenshot_from_2023-09-14_21-10-50.png&quot; alt=&quot;extension page&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Then, navigate to any page, it might get blocked:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://grgv.xyz/assets/Screenshot_from_2023-09-14_20-58-51.png&quot; alt=&quot;blocked page&quot; /&gt;&lt;/p&gt;
&lt;p&gt;After some testing I have found that gpt-3.5-turbo does not work for this task — too many obvious errors. gpt-4, on the other hand, works great! Some examples are shown in the table below, I marked in red decisions that I think are wrong.&lt;/p&gt;
&lt;table class=&quot;f5-ns f6-m f7 w-100 v-top&quot;&gt;&lt;tbody&gt;
&lt;tr class=&quot;fw6&quot;&gt;
    &lt;td&gt;GPT-4&lt;/td&gt;
    &lt;td&gt;GPU-3.5 Turbo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
    &lt;td&gt;
        &lt;a href=&quot;https://twitter.com/&quot;&gt;https://twitter.com&lt;/a&gt;&lt;br /&gt;
        &lt;b&gt;block? YES&lt;/b&gt;&lt;br /&gt;
        The website represents a social network, which could expose a child to a range of potentially harmful or inappropriate content.
    &lt;/td&gt;
    &lt;td class=&quot;dark-red&quot;&gt;
        &lt;a href=&quot;https://twitter.com/&quot;&gt;https://twitter.com&lt;/a&gt;&lt;br /&gt;
        &lt;b&gt;block? NO&lt;/b&gt;&lt;br /&gt;
        This page is from Twitter and it is a social networking site. As per the given criteria, social networks should be blocked.
    &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
    &lt;td&gt;
        &lt;a href=&quot;https://www.facebook.com/&quot;&gt;https://www.facebook.com&lt;/a&gt;&lt;br /&gt;
        &lt;b&gt;block? YES&lt;/b&gt;&lt;br /&gt;
        This is a social networking website, which is generally inappropriate for children of this age range due to the potential for exposure to inappropriate content and privacy risks.
    &lt;/td&gt;
    &lt;td class=&quot;dark-red&quot;&gt;
        &lt;a href=&quot;https://www.facebook.com/&quot;&gt;https://www.facebook.com&lt;/a&gt;&lt;br /&gt;
        &lt;b&gt;block? NO&lt;/b&gt;&lt;br /&gt;
        The web page should not be blocked. While Facebook is a social network, it does not contain explicit or inappropriate content. It can be used by children to connect with friends and family, share photos and videos, and engage in other age-appropriate activities.
    &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt; 
    &lt;td&gt;
        &lt;a href=&quot;https://en.wikipedia.org/wiki/Warsaw_Uprising&quot;&gt;https://en.wikipedia.org/wiki/Warsaw_Uprising&lt;/a&gt;&lt;br /&gt;
        &lt;b&gt;block? YES&lt;/b&gt;&lt;br /&gt;
        This page contains historical content about war, related violence and mass murder which would be inappropriate and disturbing for children under 13.
    &lt;/td&gt;
    &lt;td class=&quot;dark-red&quot;&gt;
        &lt;a href=&quot;https://en.wikipedia.org/wiki/Warsaw_Uprising&quot;&gt;https://en.wikipedia.org/wiki/Warsaw_Uprising&lt;/a&gt;&lt;br /&gt;
        &lt;b&gt;block? NO&lt;/b&gt;&lt;br /&gt;
        This webpage provides information about the Warsaw Uprising, which was a historical event during World War II. While it does mention war and destruction, it does not contain any explicit or disturbing content that would be inappropriate for children.
    &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
    &lt;td&gt;
        &lt;a href=&quot;https://platform.openai.com/apps&quot;&gt;https://platform.openai.com/apps&lt;/a&gt;&lt;br /&gt;
        &lt;b&gt;block? NO&lt;/b&gt;&lt;br /&gt;
        The webpage is about OpenAI&#39;s applications, language models, and APIs which are technological topics and tools, and it contains no content that would be inappropriate or harmful to a child.
        &lt;/td&gt;
    &lt;td class=&quot;dark-red&quot;&gt;
        &lt;a href=&quot;https://platform.openai.com/apps&quot;&gt;https://platform.openai.com/apps&lt;/a&gt;&lt;br /&gt;
        &lt;b&gt;block? YES&lt;/b&gt;&lt;br /&gt;
        The web page should be blocked because it is a login page for a platform that may contain content that is not suitable for children. As a parental control app, it is important to block access to any login pages or platforms that may potentially expose children to inappropriate content.
    &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
    &lt;td&gt;
        &lt;a href=&quot;https://www.breitbart.com/&quot;&gt;https://www.breitbart.com&lt;/a&gt;&lt;br /&gt;
        &lt;b&gt;block? YES&lt;/b&gt;&lt;br /&gt;
        This webpage contains politically charged and potentially divisive content, which may be inappropriate for children aged 2-13. The use of complex political rhetoric and potential misinformation could be confusing and potentially distressing to a child.
    &lt;/td&gt;
    &lt;td class=&quot;dark-red&quot;&gt;
        &lt;a href=&quot;https://www.breitbart.com/&quot;&gt;https://www.breitbart.com&lt;/a&gt;&lt;br /&gt;
        &lt;b&gt;block? NO&lt;/b&gt;&lt;br /&gt;
        While the content on the page contains news articles, it does not contain any explicit or inappropriate content that would disturb a child. While the content on the page contains news articles, it does not contain any explicit or inappropriate content that would disturb a child.
    &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
    &lt;td&gt;
        &lt;a href=&quot;https://www.google.com/search?q=qanon&quot;&gt;https://www.google.com/search?q=qanon&lt;/a&gt;&lt;br /&gt;
        &lt;b&gt;block? YES&lt;/b&gt;&lt;br /&gt;
        The page contains links and information about QAnon, a group known for promoting baseless conspiracy theories. Given these generally involve harmful or disturbing claims, it&#39;s inappropriate for children.
        &lt;/td&gt;
    &lt;td&gt;
        &lt;a href=&quot;https://www.google.com/search?q=qanon&quot;&gt;https://www.google.com/search?q=qanon&lt;/a&gt;&lt;br /&gt;
        &lt;b&gt;block? YES&lt;/b&gt;&lt;br /&gt;
        The content of the webpage includes information about QAnon, which is a conspiracy theory and political movement. Considering the guidelines given, this content should be blocked to protect children from exposure to potentially harmful and inappropriate information.
    &lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;problems&lt;/h3&gt;
&lt;p&gt;There are several problems that have to be solved before this extension can be used in practice:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;After the page is loaded, it’s content is hidden behind an overlay, while waiting for the LLM response. The problem is that there is a short delay before the overlay is added, so the page is visible briefly. This is not  good for sites with prominent explicit graphical content. Probably, need to use &lt;em&gt;WebRequest&lt;/em&gt; API to analyze content before the page is loaded?&lt;/li&gt;
&lt;li&gt;GPT-4 works well, but each request costs ~$0.03. This has to be optimized, possibly with finetuning of a smaller/cheaper model. Another approach would be to use a cascaded system, where only some of the requests would be sent to GPT-4, while most decisions would be handled by a smaller model.&lt;/li&gt;
&lt;li&gt;Installation is not very user-friendly, and sending requests from a browser is not great, the extension needs authentication and a dedicated backend.&lt;/li&gt;
&lt;li&gt;OpenAI API is quite slow, it takes several seconds to validate each page. Although this might be a good feature, it makes web browsing more mindful.&lt;/li&gt;
&lt;li&gt;The main issue is of course proper testing. It would be irresponsible to not validate a parental control application on a large dataset, to check if there are any random glitches and hallucinations affecting content classification accuracy.&lt;/li&gt;
&lt;/ul&gt;

</content>
  </entry>
  <entry>
    <title>Browser-based robot dog simulator: walking controller</title>
    <link href="https://grgv.xyz/blog/simulator4/"/>
    <updated>2023-08-01T00:00:00Z</updated>
    <id>https://grgv.xyz/blog/simulator4/</id>
    <content xml:lang="en" type="html">
&lt;p&gt;Previously, I have implemented a &lt;a href=&quot;https://grgv.xyz/blog/simulator3/&quot;&gt;controller for a quadruped robot for stepping in place&lt;/a&gt;. It is a good starting point for implementing a controller for walking.&lt;/p&gt;
&lt;h3&gt;targets for placing feet&lt;/h3&gt;
&lt;p&gt;The only difference between stepping in place and walking — is selecting target points for lifting and planting feet.&lt;/p&gt;
&lt;p&gt;An idea that is frequently used in procedural animation is to set this target points relative to the character’s torso. Then, when torso is moved, feet always automatically follow the torso, and step in the same direction.&lt;/p&gt;
&lt;p&gt;Three.js already supports hierarchy of objects, so the only thing that&#39;s changing is putting the torso object as a parent for the feet targets objects.&lt;/p&gt;
&lt;p&gt;For stepping in place, feet target points are attached to three.js scene, and do not change position:&lt;/p&gt;
&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;step_targets&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;j&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;THREE&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Mesh&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;step_targets&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;j&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;geometry &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;THREE&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;SphereGeometry&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.01&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;step_targets&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;j&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;material &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;THREE&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;MeshLambertMaterial&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
scene&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;step_targets&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;j&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And for walking, they are attached to the torso object, and move along with it:&lt;/p&gt;
&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;step_targets&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;j&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;THREE&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Mesh&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;step_targets&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;j&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;geometry &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;THREE&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;SphereGeometry&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.01&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;step_targets&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;j&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;material &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;THREE&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;MeshLambertMaterial&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;targets&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;trunk&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;step_targets&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;j&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;video controls=&quot;&quot; class=&quot;w-100&quot;&gt;
  &lt;source src=&quot;https://meek-pony-a3b971.netlify.app/ranger_aug_2023_04_2.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;
&lt;p&gt;The video shows how feet targets (&lt;em&gt;this.step_targets&lt;/em&gt; from the code above, shown with white spheres) move with the torso.&lt;/p&gt;
&lt;h3&gt;walking motion generation&lt;/h3&gt;
&lt;p&gt;In the &lt;a href=&quot;https://grgv.xyz/blog/simulator3/&quot;&gt;post about stepping in place&lt;/a&gt;, I have posted the code for the motion generation. Code for walking motion is mostly the same — the only difference is transforming feet targets from local coordinates (relative to the torso), into world space coordinates.&lt;/p&gt;
&lt;p&gt;Code for stepping in place:&lt;/p&gt;
&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// set the target for lifting the foot&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// it&#39;s the same as the initial standing position&lt;/span&gt;
s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;goal &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;step_targets&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;position&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;clone&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// only raised 0.1m above ground&lt;/span&gt;
s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;goal&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.1&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And code modified to support walking:&lt;/p&gt;
&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// set the target for lifting the foot&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// from the point attached to the torso&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; w &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;THREE&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Vector3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;step_targets&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getWorldPosition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;w&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; 
s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;goal &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; w&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// raised 0.1m above ground&lt;/span&gt;
s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;goal&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This approach to motion generation is quite flexible, it works for different variations of gaits, for different directions of walking, and for turning:&lt;/p&gt;
&lt;video controls=&quot;&quot; class=&quot;w-100&quot;&gt;
  &lt;source src=&quot;https://meek-pony-a3b971.netlify.app/ranger_aug_2023_05_2.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/coolvision/ranger/tree/a1&quot;&gt;Code is on github&lt;/a&gt;, and an interactive demo with first-person control of the robot is below. Use WASD keys on keyboard or on the screen for moving the robot.&lt;/p&gt;
&lt;div class=&quot;container&quot;&gt;
  &lt;iframe class=&quot;responsive-iframe&quot; src=&quot;https://grgv.xyz/demo/ranger_demo_Aug_2023_03/&quot;&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;This is a nice and simple approach, and I’m quite happy with how compact the code is. There are limitations of course:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;There is no sensing and no feedback loop, so if robots loses the balance, it will not recover and will most likely fall. A quadruped is quite a stable platform, but it&#39;s still easy to put it off balance by moving and turning abruptly.&lt;/li&gt;
&lt;li&gt;Simulation parameters are approximate, I tweaked values for the robot’s weight and for the motors settings; support for realistic parameters needs more work&lt;/li&gt;
&lt;li&gt;Only walking on flat surface is supported, any obstacles or elevation changes will lead to losing the balance&lt;/li&gt;
&lt;/ul&gt;

</content>
  </entry>
  <entry>
    <title>Procedural animation for controlling a (simulated) robot dog: first steps</title>
    <link href="https://grgv.xyz/blog/simulator3/"/>
    <updated>2023-08-01T00:00:00Z</updated>
    <id>https://grgv.xyz/blog/simulator3/</id>
    <content xml:lang="en" type="html">
&lt;p&gt;My &lt;a href=&quot;https://grgv.xyz/blog/simulator2/&quot;&gt;previous post&lt;/a&gt; was about implementing a simulator for a quadruped robot. I got it to work, including inverse kinematics for controlling robot’s feet and torso poses. Next step is making the simulated model move and walk. How hard can it be?&lt;/p&gt;
&lt;h3&gt;procedural animation&lt;/h3&gt;
&lt;p&gt;The simplest way to generate walking motion is very similar to &lt;a href=&quot;https://en.wikipedia.org/wiki/Procedural_animation&quot;&gt;procedural animation&lt;/a&gt;. It imitates motion by setting poses of some of the character’s body parts and applying physics simulation to the rest. The character in this case is supported with external constraints, it’s more like a puppet instead of a fully simulated self-supported robot.&lt;/p&gt;
&lt;p&gt;My idea is to use procedurally animated model to indirectly drive the “real” robot model. Just need to measure angles of the animated model’s joints, and use this angles as targets for motors of the actual simulated robot’s model.&lt;/p&gt;
&lt;h3&gt;stepping in place&lt;/h3&gt;
&lt;p&gt;Let’s start with just stepping in place. If robot’s legs are controlled with inverse kinematics, the the only thing needed is to raise and lower the feet. For the &lt;a href=&quot;https://en.wikipedia.org/wiki/Trot&quot;&gt;trot gait&lt;/a&gt;&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://grgv.xyz/blog/simulator3/#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;, only one of the diagonal pairs of feet is moved, while another pair stays on the ground.&lt;/p&gt;
&lt;p&gt;This can be managed with a simple state machine. Each of the feet goes through a sequence of states: &lt;em&gt;&lt;strong&gt;ground→lift→plant→ground&lt;/strong&gt;&lt;/em&gt;. Diagonal pairs of feet go into this sequence alternatively on every other step. Here is how the code looks:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;UnitreeA1&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// identifiers for the feet: front left, rear right...&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;feet_names &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;FL_foot&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;FR_foot&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;RL_foot&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;RR_foot&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;feet_states &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// structure for feet state machines&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; f &lt;span class=&quot;token keyword&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;feet_names&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;feet_states&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;f&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token literal-property property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;ground&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// ground, lift, plant&lt;/span&gt;
                &lt;span class=&quot;token literal-property property&quot;&gt;goal&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;// target point for moving the foot &lt;/span&gt;
                &lt;span class=&quot;token literal-property property&quot;&gt;goal_distance&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token literal-property property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; f
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;step_i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

   &lt;span class=&quot;token function&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; w &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;THREE&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Vector3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// count number of feet on the ground&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; n_ground &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; j &lt;span class=&quot;token keyword&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;feet_names&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;feet_states&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;j&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;ground&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; n_ground&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// only start the next step when all 4 feet are on the ground&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;n_ground &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;step_i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// select which feet to move&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; selected &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;step_i &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// on even steps, select front left and rear right feet&lt;/span&gt;
            selected&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;feet_states&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;RR_foot&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            selected&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;feet_states&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;FL_foot&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// on odd steps, select front right and rear left feet&lt;/span&gt;
            selected&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;feet_states&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;RL_foot&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            selected&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;feet_states&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;FR_foot&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;n_ground &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// when all 4 feet are on the ground&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// start the next step: put selected feet into the &quot;lift&quot; state&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; s &lt;span class=&quot;token keyword&quot;&gt;of&lt;/span&gt; selected&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;lift&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token comment&quot;&gt;// set target point for lifting as default stading position&lt;/span&gt;
                &lt;span class=&quot;token comment&quot;&gt;// raised 0.1m above ground&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;step_targets&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getWorldPosition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;w&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; 
                s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;goal &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; w&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;clone&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;goal&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// raise the root&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// move feet positions towards goal points, by 0.05m at a time&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; j &lt;span class=&quot;token keyword&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;feet_names&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; 
            &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;feet_states&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;j&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;goal_distance &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; 
                &lt;span class=&quot;token function&quot;&gt;move_towards&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;targets&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;j&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;position&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
                             &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;feet_states&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;j&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;goal&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.05&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// if all feet have reached the goal points&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;selected&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;every&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; v&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;goal_distance &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.001&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;selected&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;every&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; v&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;lift&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token comment&quot;&gt;// if reached the &quot;lift&quot; goal, switch to &quot;plant&quot;&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; s &lt;span class=&quot;token keyword&quot;&gt;of&lt;/span&gt; selected&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token comment&quot;&gt;// the goal for planting the foot is detault standing position&lt;/span&gt;
                    &lt;span class=&quot;token comment&quot;&gt;// s.goal = this.step_targets[s.name].position.clone();&lt;/span&gt;
                    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;step_targets&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getWorldPosition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;w&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; 
                    s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;goal &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; w&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;clone&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                    s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;goal&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.02&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                    s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;plant&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;selected&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;every&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; v&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;plant&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token comment&quot;&gt;// if reached the &quot;plant&quot; goal, the foot is on the ground &lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; s &lt;span class=&quot;token keyword&quot;&gt;of&lt;/span&gt; selected&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;ground&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;step()&lt;/strong&gt;&lt;/em&gt; is called at 30Hz. Here is how the resulting motion looks:&lt;/p&gt;
&lt;video controls=&quot;&quot; loop=&quot;&quot; class=&quot;w-100&quot;&gt;
  &lt;source src=&quot;https://meek-pony-a3b971.netlify.app/ranger_aug_2023_01.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;
&lt;p&gt;There are two robot models in the video, model on the left is animated by setting it’s feet positions. Then it’s joints angles are transferred to the model on the right, which is the unconstrained full simulation model.&lt;/p&gt;
&lt;p&gt;The simulation model bounces after stepping. Rapier.js physics engine supports only rigid bodies simulation, so the feet collide with the ground hard. In the real robot, feet pads are elastic, which provides damping. A quick fix is to add a short delay after planting the foot, at least it allows the model to settle. Here is how the model with the delay looks, in this case bouncing is reduced:&lt;/p&gt;
&lt;video controls=&quot;&quot; loop=&quot;&quot; class=&quot;w-100&quot;&gt;
  &lt;source src=&quot;https://meek-pony-a3b971.netlify.app/ranger_aug_2023_02.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;
&lt;p&gt;So this works well, but what happens when the robot tries to move forward while stepping in place? It will tilt and fall:&lt;/p&gt;
&lt;video controls=&quot;&quot; class=&quot;w-100&quot;&gt;
  &lt;source src=&quot;https://meek-pony-a3b971.netlify.app/ranger_aug_2023_03.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/coolvision/ranger/tree/a1&quot;&gt;Code is on github&lt;/a&gt;, and a live demo is below:&lt;/p&gt;
&lt;div class=&quot;container&quot;&gt;
  &lt;iframe class=&quot;responsive-iframe&quot; src=&quot;https://grgv.xyz/demo/ranger_demo_Aug_2023_02/&quot;&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;Next, &lt;a href=&quot;http://localhost:8080/blog/simulator4/&quot;&gt;implementing walking motion generation&lt;/a&gt;.&lt;/p&gt;
&lt;hr class=&quot;footnotes-sep&quot; /&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Or, in case of stepping in place, this can be called a &lt;em&gt;piaffe&lt;/em&gt;: &lt;a href=&quot;https://en.wikipedia.org/wiki/Piaffe&quot;&gt;&amp;quot;The piaffe (French pronunciation: [pjaf]) is a dressage movement where the horse is in a highly collected and cadenced trot, in place or nearly in place&amp;quot;&lt;/a&gt; &lt;a href=&quot;https://grgv.xyz/blog/simulator3/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;

</content>
  </entry>
  <entry>
    <title>Browser-based robot dog simulator</title>
    <link href="https://grgv.xyz/blog/simulator2/"/>
    <updated>2023-07-01T00:00:00Z</updated>
    <id>https://grgv.xyz/blog/simulator2/</id>
    <content xml:lang="en" type="html">
&lt;p&gt;I’m continuing to &lt;a href=&quot;https://grgv.xyz/blog/simulator/&quot;&gt;learn about robot simulation&lt;/a&gt;, and the next step is simulating a real robot, rather than a simplified platform.&lt;/p&gt;
&lt;p&gt;I’ve chosen a quadruped (Unitree A1) for the next demo. First step is to load robot description from the &lt;a href=&quot;https://github.com/unitreerobotics/unitree_ros&quot;&gt;official repository&lt;/a&gt;, using &lt;a href=&quot;https://github.com/gkjohnson/urdf-loaders&quot;&gt;urdf-loaders library&lt;/a&gt;. Next, robot’s links and joints can be created in &lt;a href=&quot;https://github.com/dimforge/rapier.js&quot;&gt;rapier.js&lt;/a&gt; physics engine for simulation and added to a three.js scene for visualization. For each loaded robot body part, we need to create:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;rapier.js rigid body object and corresponding three.js mesh&lt;/li&gt;
&lt;li&gt;rapier.js collider object&lt;/li&gt;
&lt;li&gt;rapier.js joints for linking body parts together&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Physics model connected with joints works well for inverse kinematics, when some of the model’s parts positions are set with 3d controls. We set positions of robot’s torso ans feet, and the rest of the parts and joints poses are then computed based on the physics simulation. Interactive demo is shown below. Let’s call this the &lt;em&gt;&lt;strong&gt;control model&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;div class=&quot;container&quot;&gt;
    &lt;iframe class=&quot;responsive-iframe&quot; src=&quot;https://grgv.xyz/demo/ranger_demo_jul_2023_01/&quot;&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;Inverse kinematics can be used to drive another robot model, which actually simulates robot’s body dynamics. Let’s call this &lt;em&gt;&lt;strong&gt;simulation model&lt;/strong&gt;&lt;/em&gt;. This model’s parts poses are are not constrained, and are controlled by setting joints motors/angles. Angles values are obtained from measuring angles between body parts of the &lt;em&gt;&lt;strong&gt;control model&lt;/strong&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Next demo shows 2 models, &lt;em&gt;&lt;strong&gt;control model&lt;/strong&gt;&lt;/em&gt; on the left and &lt;em&gt;&lt;strong&gt;simulation model&lt;/strong&gt;&lt;/em&gt; on the right. &lt;em&gt;&lt;strong&gt;Control model&lt;/strong&gt;&lt;/em&gt; can be interactively manipulated, and it sets the pose of the &lt;em&gt;&lt;strong&gt;simulation model&lt;/strong&gt;&lt;/em&gt;, which is a proper physics/dynamics model.&lt;/p&gt;
&lt;div class=&quot;container&quot;&gt;
  &lt;iframe class=&quot;responsive-iframe&quot; src=&quot;https://grgv.xyz/demo/ranger_demo_jul_2023_02/&quot;&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;The whole project is &lt;a href=&quot;https://github.com/coolvision/ranger/tree/a1&quot;&gt;~800 LOC&lt;/a&gt;, which is quite compact for a realistic 3d robot simulator. I do believe that existing robotics simulators are frequently over-engineered, and it looks that some parts of a simulator can be simplified by relying on WebGL and WASM.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://grgv.xyz/blog/simulator3/&quot;&gt;Next, implementing a motion controller&lt;/a&gt;.&lt;/p&gt;

</content>
  </entry>
  <entry>
    <title>Browser-based robot simulator with three.js &amp; rapier.js</title>
    <link href="https://grgv.xyz/blog/simulator/"/>
    <updated>2023-03-01T00:00:00Z</updated>
    <id>https://grgv.xyz/blog/simulator/</id>
    <content xml:lang="en" type="html">
&lt;p&gt;While learning more about embodied AI and robot simulation i’m building a simple simulator, based on &lt;a href=&quot;https://threejs.org/&quot;&gt;Three.js&lt;/a&gt; and &lt;a href=&quot;https://rapier.rs/&quot;&gt;Rapier physics engine&lt;/a&gt;.&lt;/p&gt;
&lt;video controls=&quot;&quot; class=&quot;w-100&quot;&gt;
  &lt;source src=&quot;https://meek-pony-a3b971.netlify.app/ranger_mar_2023.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;
&lt;p&gt;The robot model is a mobile platform with a 6DOF manipulator and a 2-finger gripper. Each part of the robot is a three.js mesh, kept in sync with the Rapier rigid body. Parts are connected into a kinematic chain with Rapier joints. Arm pose can be set by dragging the gripper with three.js TransformControls.&lt;/p&gt;
&lt;p&gt;Surprisingly, inverse kinematics works just based on physics simulation, without the need for an additional explicit solver.&lt;/p&gt;
&lt;video controls=&quot;&quot; class=&quot;w-100&quot;&gt;
  &lt;source src=&quot;https://meek-pony-a3b971.netlify.app/ranger_mar_2023_ik.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;
&lt;p&gt;It even has advanced features like self-collision aware motion planning, example of self-collision avoidance is shown below:&lt;/p&gt;
&lt;video controls=&quot;&quot; class=&quot;w-100&quot;&gt;
  &lt;source src=&quot;https://meek-pony-a3b971.netlify.app/ranger_mar_2023_ik5.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;
&lt;p&gt;Initially, I assumed that adding inverse kinematics would be the hardest part of the project, so it’s nice that it comes for free. Compared to a proper IK solver, physics based IK is less accurate, it&#39;s not optimal, and there is less control over resulting trajectories. But simplicity is still a big benefit.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/coolvision/ranger&quot;&gt;Code is on github&lt;/a&gt;, and live demo is below.&lt;/p&gt;
&lt;p&gt;Keyboard controls for the demo:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;WASD: move the platform&lt;/li&gt;
&lt;li&gt;G: open/close gripper&lt;/li&gt;
&lt;li&gt;T, R: translate or rotate the gripper&lt;/li&gt;
&lt;li&gt;Z: toggle zoom with scrolling&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;container&quot;&gt;
  &lt;iframe class=&quot;responsive-iframe&quot; src=&quot;https://grgv.xyz/demo/ranger_demo_mar_2023/&quot;&gt;&lt;/iframe&gt;
&lt;/div&gt;

</content>
  </entry>
</feed>