Smiley face

我的征尘是星辰大海。。。

The dirt and dust from my pilgrimage forms oceans of stars...

-------当记忆的篇章变得零碎,当追忆的图片变得模糊,我们只能求助于数字存储的永恒的回忆

作者:黄教授

二〇二四


一月四日 等待变化等待机会

  1. 我发现ubuntu标准包的vscode似乎不太稳定,还是这个snap的好一些吧。我尝试要从源代码编译,但是遇到node.js的版本要求,这个东西我不熟悉,虽然看起来可以直接安装,但是多版本运行肯定麻烦。就放弃了。
    
    sudo snap install --classic code
    
    这里是ubuntu的源代码,难道想从源码编译吗?
  2. 阅读我以前的笔记发现了一个问题。难得发现了一个clang的继承类的问题。这里又遇到一个微妙的问题,就是当你有多重继承的时候,这里的public是要覆盖到所有的基类的,否则就是private了。 注意这里的class Virus : public T, public Ts... 第二个public,如果没有的话,那么除了第一个基类其他的就都是privately inherited了,这个是一个非常细微的地方!对于这个问题,GCC,还是MSVC都给出了出错信息,唯独clang错误的接受了,这个是比较罕见的。
  3. 关于c++的标准你在这里下载。
    1. 编译
    首先,你还是要下载这个latex的编译工具。说明里要你安装必要的工具: 额外的是所谓的tex2html,这个不能由npm来安装。
  4. 始终都有编译出错的问题,我决定尝试大师的一个修正draft的repo
  5. 似乎安装haskell有些问题,这里说从2022年开始要这么安装:
    
    curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh
    
  6. 需要重头学习制作ami

一月八日 等待变化等待机会

  1. 这个是配置openvpn的全部教程。其中这里是如何创建CA的步骤,我一直认为这个不是必须的,也许我是错的,不仅是浏览器出现警告那么简单吧?
  2. 这个设定openvpn的教程我始终无法成功。

一月十一日 等待变化等待机会

  1. 与其费力去创建vpn还是proxy,我直接的目的是编译c++标准的网页,所以,我直接部署一个aws/ec2的实例在上面试验就行了吧?距离我上一次密集使用aws已经过去整整十年了,可以说几乎完全的翻天覆地。
    1. 首先,登陆的方法都加强了,我之前被折磨的半死就是所谓的time-based-password系统,我现在是使用microsoft的authenticator来生成密码。这个美国手机简直太要命了,完全离不开。
    2. 找到官方的ubuntu/ami,这个是在所谓的ami catalog里免费的。
    3. 配置ubuntu当然是基本的,只是我不熟悉这些个npm/cabal,需要cabal update安装haskell的包,原本就是卡在这里的。
    4. 我使用的是便宜的micro instance,导致编译几乎停滞。现在可以在monitor里看到cpu的使用率一直在99%。
    最后我遇到内存不足的问题,但是使用了超大实例依然有和我本地类似的编译错误。于是我转而尝试ubuntu18.04的环境发现依赖的包都版本不支持,看来是要使用最新版的ubuntu才行。这时候我想起了另一位大师的做法,也许他的一些补丁修改可以吧?结果我又忘记要把依赖的子模块都clone,所以,只能这样子: git clone --recursive https://github.com/timsong-cpp/cppwp
  2. 随后我又遇到另一个老问题,就是github有了严格的认证制度,下载某些代码需要使用publickey,我只好去github生成我的key,实际上是把我本地的pubkey拷贝到github,那么在我的instance里拷贝我的privatekey,这个当然是很冒险的。没有办法。
  3. 我有点明白所谓的几个脚本实际上是编译c++几个不同标准部分的脚本,比如range,比如network,和具体的编译工具无关,于是我又回到编译工具尝试使用stack build。这些名字对我来说完全不明白是什么,到底是haskell还是node.js,其实我也没兴趣也没能力搞明白。

一月十二日 等待变化等待机会

  1. 之前我设定的github的workaround又反过来害我了:
    
    url.https://github.com/.insteadof=git@github.com:
    url.https://gitclone.com/.insteadof=git://gitclone.com/
    url.https://.insteadof=ssh://
    url.https://.insteadof=git://
    http.sslverify=false
    
    赶紧全部取消掉!
    [url "https://github.com/"]
            insteadof = git@github.com:
    [url "https://gitclone.com/"]
            insteadof = git://gitclone.com/
    [url "https://"]
      insteadOf = ssh://
    [url "https://"]
      insteadOf = git://
    [http]
            sslVerify = false
    
  2. 我编译不过大师的cxxhtmlgen,就提了这么一个bug,实际上是想要获得相应的帮助,大师明确指出了方向,这个tex2html是在所谓的mathjax-node-cli里的脚本。原本它就是编译的前提,是我自己不明白,一直以为npm已经解决了。我发现不如去尝试从mathjax-src来直接编译一下:
    
    git clone https://github.com/mathjax/MathJax-src.git mathjax-src
    cd mathjax-src
    npm run --silent compile
    npm run --silent make-components
    
    我现在都要把命令抄录下来因为中国政府不知道什么时候又把这些给屏蔽了,或许也不是中国屏蔽而是美国屏蔽了,总之,现在的世界很有可能是分裂的世界。
  3. 这里是遇到npm卡住的办法,试一下再说。
  4. 我不知道具体是怎么解决了,总之,我编译的mathjax-node-cli作为component需要一个mathjax-node-sre作为前提,然后我对于怎么安装component实在是想不出来最后只好把mathjax-node-cli下的bin的脚本生生的拷贝软链接。比如
    
    cd /usr/local/bin
    sudo ln -s /path/to/mathjax-node-cli/bin/* .
    
    因为归根结柢编译时候需要执行tex2html作为node.js的外部命令。最后的确是编译了两千多个文件。
  5. 我打算把它们保存在这里:www.staroceans.org/cxx/index.html
  6. 如何列表文件不是什么扩展名的呢?比如不是.html的文件,我还真的不知道:ls | grep -v .html
  7. 然后我就发现了有几个.css文件,它的正确的mime-type是:application/x-pointplus
  8. 我又要拷贝一下这个mimetype表了。
    Suffixes applicable Media type and subtype(s)
    .3dm x-world/x-3dmf
    .3dmf x-world/x-3dmf
    .7z application/x-7z-compressed
    .a application/octet-stream
    .aab application/x-authorware-bin
    .aam application/x-authorware-map
    .aas application/x-authorware-seg
    .abc text/vnd.abc
    .acgi text/html
    .afl video/animaflex
    .ai application/postscript
    .aif audio/aiff
    .aif audio/x-aiff
    .aifc audio/aiff
    .aifc audio/x-aiff
    .aiff audio/aiff
    .aiff audio/x-aiff
    .aim application/x-aim
    .aip text/x-audiosoft-intra
    .ani application/x-navi-animation
    .aos application/x-nokia-9000-communicator-add-on-software
    .aps application/mime
    .arc application/octet-stream
    .arj application/arj
    .arj application/octet-stream
    .art image/x-jg
    .asf video/x-ms-asf
    .asm text/x-asm
    .asp text/asp
    .asx application/x-mplayer2
    .asx video/x-ms-asf
    .asx video/x-ms-asf-plugin
    .au audio/basic
    .au audio/x-au
    .avi application/x-troff-msvideo
    .avi video/avi
    .avi video/msvideo
    .avi video/x-msvideo
    .avs video/avs-video
    .bcpio application/x-bcpio
    .bin application/mac-binary
    .bin application/macbinary
    .bin application/octet-stream
    .bin application/x-binary
    .bin application/x-macbinary
    .bm image/bmp
    .bmp image/bmp
    .bmp image/x-windows-bmp
    .boo application/book
    .book application/book
    .boz application/x-bzip2
    .bsh application/x-bsh
    .bz application/x-bzip
    .bz2 application/x-bzip2
    .c text/plain
    .c text/x-c
    .c++ text/plain
    .cat application/vnd.ms-pki.seccat
    .cc text/plain
    .cc text/x-c
    .ccad application/clariscad
    .cco application/x-cocoa
    .cdf application/cdf
    .cdf application/x-cdf
    .cdf application/x-netcdf
    .cer application/pkix-cert
    .cer application/x-x509-ca-cert
    .cha application/x-chat
    .chat application/x-chat
    .class application/java
    .class application/java-byte-code
    .class application/x-java-class
    .com application/octet-stream
    .com text/plain
    .conf text/plain
    .cpio application/x-cpio
    .cpp text/x-c
    .cpt application/mac-compactpro
    .cpt application/x-compactpro
    .cpt application/x-cpt
    .crl application/pkcs-crl
    .crl application/pkix-crl
    .crt application/pkix-cert
    .crt application/x-x509-ca-cert
    .crt application/x-x509-user-cert
    .csh application/x-csh
    .csh text/x-script.csh
    .css application/x-pointplus
    .css text/css
    .csv text/csv
    .cxx text/plain
    .dcr application/x-director
    .deepv application/x-deepv
    .def text/plain
    .der application/x-x509-ca-cert
    .dif video/x-dv
    .dir application/x-director
    .dl video/dl
    .dl video/x-dl
    .doc application/msword
    .docx application/vnd.openxmlformats-officedocument.wordprocessingml.document
    .dot application/msword
    .dp application/commonground
    .drw application/drafting
    .dump application/octet-stream
    .dv video/x-dv
    .dvi application/x-dvi
    .dwf drawing/x-dwf (old)
    .dwf model/vnd.dwf
    .dwg application/acad
    .dwg image/vnd.dwg
    .dwg image/x-dwg
    .dxf application/dxf
    .dxf image/vnd.dwg
    .dxf image/x-dwg
    .dxr application/x-director
    .el text/x-script.elisp
    .elc application/x-bytecode.elisp (compiled elisp)
    .elc application/x-elc
    .env application/x-envoy
    .eot application/vnd.ms-fontobject
    .eps application/postscript
    .es application/x-esrehber
    .etx text/x-setext
    .evy application/envoy
    .evy application/x-envoy
    .exe application/octet-stream
    .f text/plain
    .f text/x-fortran
    .f77 text/x-fortran
    .f90 text/plain
    .f90 text/x-fortran
    .fdf application/vnd.fdf
    .fif application/fractals
    .fif image/fif
    .flac audio/flac
    .fli video/fli
    .fli video/x-fli
    .flo image/florian
    .flx text/vnd.fmi.flexstor
    .fmf video/x-atomic3d-feature
    .for text/plain
    .for text/x-fortran
    .fpx image/vnd.fpx
    .fpx image/vnd.net-fpx
    .frl application/freeloader
    .funk audio/make
    .g text/plain
    .g3 image/g3fax
    .gif image/gif
    .gl video/gl
    .gl video/x-gl
    .gsd audio/x-gsm
    .gsm audio/x-gsm
    .gsp application/x-gsp
    .gss application/x-gss
    .gtar application/x-gtar
    .gz application/x-compressed
    .gz application/x-gzip
    .gzip application/x-gzip
    .gzip multipart/x-gzip
    .h text/plain
    .h text/x-h
    .hdf application/x-hdf
    .help application/x-helpfile
    .hgl application/vnd.hp-hpgl
    .hh text/plain
    .hh text/x-h
    .hlb text/x-script
    .hlp application/hlp
    .hlp application/x-helpfile
    .hlp application/x-winhelp
    .hpg application/vnd.hp-hpgl
    .hpgl application/vnd.hp-hpgl
    .hqx application/binhex
    .hqx application/binhex4
    .hqx application/mac-binhex
    .hqx application/mac-binhex40
    .hqx application/x-binhex40
    .hqx application/x-mac-binhex40
    .hta application/hta
    .htc text/x-component
    .htm text/html
    .html text/html
    .htmls text/html
    .htt text/webviewhtml
    .htx text/html
    .ice x-conference/x-cooltalk
    .ico image/x-icon
    .ics text/calendar
    .idc text/plain
    .ief image/ief
    .iefs image/ief
    .iges application/iges
    .iges model/iges
    .igs application/iges
    .igs model/iges
    .ima application/x-ima
    .imap application/x-httpd-imap
    .inf application/inf
    .ins application/x-internett-signup
    .ip application/x-ip2
    .isu video/x-isvideo
    .it audio/it
    .iv application/x-inventor
    .ivr i-world/i-vrml
    .ivy application/x-livescreen
    .jam audio/x-jam
    .jav text/plain
    .jav text/x-java-source
    .java text/plain
    .java text/x-java-source
    .jcm application/x-java-commerce
    .jfif image/jpeg
    .jfif image/pjpeg
    .jfif-tbnl image/jpeg
    .jpe image/jpeg
    .jpe image/pjpeg
    .jpeg image/jpeg
    .jpeg image/pjpeg
    .jpg image/jpeg
    .jpg image/pjpeg
    .jps image/x-jps
    .js application/x-javascript
    .js application/javascript
    .js application/ecmascript
    .js text/javascript
    .js text/ecmascript
    .json application/json
    .jut image/jutvision
    .kar audio/midi
    .kar music/x-karaoke
    .ksh application/x-ksh
    .ksh text/x-script.ksh
    .la audio/nspaudio
    .la audio/x-nspaudio
    .lam audio/x-liveaudio
    .latex application/x-latex
    .lha application/lha
    .lha application/octet-stream
    .lha application/x-lha
    .lhx application/octet-stream
    .list text/plain
    .lma audio/nspaudio
    .lma audio/x-nspaudio
    .log text/plain
    .lsp application/x-lisp
    .lsp text/x-script.lisp
    .lst text/plain
    .lsx text/x-la-asf
    .ltx application/x-latex
    .lzh application/octet-stream
    .lzh application/x-lzh
    .lzx application/lzx
    .lzx application/octet-stream
    .lzx application/x-lzx
    .m text/plain
    .m text/x-m
    .m1v video/mpeg
    .m2a audio/mpeg
    .m2v video/mpeg
    .m3u audio/x-mpequrl
    .man application/x-troff-man
    .map application/x-navimap
    .mar text/plain
    .mbd application/mbedlet
    .mc$ application/x-magic-cap-package-1.0
    .mcd application/mcad
    .mcd application/x-mathcad
    .mcf image/vasa
    .mcf text/mcf
    .mcp application/netmc
    .me application/x-troff-me
    .mht message/rfc822
    .mhtml message/rfc822
    .mid application/x-midi
    .mid audio/midi
    .mid audio/x-mid
    .mid audio/x-midi
    .mid music/crescendo
    .mid x-music/x-midi
    .midi application/x-midi
    .midi audio/midi
    .midi audio/x-mid
    .midi audio/x-midi
    .midi music/crescendo
    .midi x-music/x-midi
    .mif application/x-frame
    .mif application/x-mif
    .mime message/rfc822
    .mime www/mime
    .mjf audio/x-vnd.audioexplosion.mjuicemediafile
    .mjpg video/x-motion-jpeg
    .mka audio/x-matroska
    .mkv video/x-matroska
    .mm application/base64
    .mm application/x-meme
    .mme application/base64
    .mod audio/mod
    .mod audio/x-mod
    .moov video/quicktime
    .mov video/quicktime
    .movie video/x-sgi-movie
    .mp2 audio/mpeg
    .mp2 audio/x-mpeg
    .mp2 video/mpeg
    .mp2 video/x-mpeg
    .mp2 video/x-mpeq2a
    .mp3 audio/mpeg3
    .mp3 audio/x-mpeg-3
    .mp3 video/mpeg
    .mp3 video/x-mpeg
    .mp4 video/mp4
    .mpa audio/mpeg
    .mpa video/mpeg
    .mpc application/x-project
    .mpe video/mpeg
    .mpeg video/mpeg
    .mpg audio/mpeg
    .mpg video/mpeg
    .mpga audio/mpeg
    .mpp application/vnd.ms-project
    .mpt application/x-project
    .mpv application/x-project
    .mpx application/x-project
    .mrc application/marc
    .ms application/x-troff-ms
    .mv video/x-sgi-movie
    .my audio/make
    .mzz application/x-vnd.audioexplosion.mzz
    .nap image/naplps
    .naplps image/naplps
    .nc application/x-netcdf
    .ncm application/vnd.nokia.configuration-message
    .nif image/x-niff
    .niff image/x-niff
    .nix application/x-mix-transfer
    .nsc application/x-conference
    .nvd application/x-navidoc
    .o application/octet-stream
    .oda application/oda
    .ogg audio/ogg
    .ogg video/ogg
    .omc application/x-omc
    .omcd application/x-omcdatamaker
    .omcr application/x-omcregerator
    .otf font/otf
    .p text/x-pascal
    .p10 application/pkcs10
    .p10 application/x-pkcs10
    .p12 application/pkcs-12
    .p12 application/x-pkcs12
    .p7a application/x-pkcs7-signature
    .p7c application/pkcs7-mime
    .p7c application/x-pkcs7-mime
    .p7m application/pkcs7-mime
    .p7m application/x-pkcs7-mime
    .p7r application/x-pkcs7-certreqresp
    .p7s application/pkcs7-signature
    .part application/pro_eng
    .pas text/pascal
    .pbm image/x-portable-bitmap
    .pcl application/vnd.hp-pcl
    .pcl application/x-pcl
    .pct image/x-pict
    .pcx image/x-pcx
    .pdb chemical/x-pdb
    .pdf application/pdf
    .pfunk audio/make
    .pfunk audio/make.my.funk
    .pgm image/x-portable-graymap
    .pgm image/x-portable-greymap
    .pic image/pict
    .pict image/pict
    .pkg application/x-newton-compatible-pkg
    .pko application/vnd.ms-pki.pko
    .pl text/plain
    .pl text/x-script.perl
    .plx application/x-pixclscript
    .pm image/x-xpixmap
    .pm text/x-script.perl-module
    .pm4 application/x-pagemaker
    .pm5 application/x-pagemaker
    .png image/png
    .pnm application/x-portable-anymap
    .pnm image/x-portable-anymap
    .pot application/mspowerpoint
    .pot application/vnd.ms-powerpoint
    .pov model/x-pov
    .ppa application/vnd.ms-powerpoint
    .ppm image/x-portable-pixmap
    .pps application/mspowerpoint
    .pps application/vnd.ms-powerpoint
    .ppt application/mspowerpoint
    .ppt application/powerpoint
    .ppt application/vnd.ms-powerpoint
    .ppt application/x-mspowerpoint
    .pptx application/vnd.openxmlformats-officedocument.presentationml.presentation
    .ppz application/mspowerpoint
    .pre application/x-freelance
    .prt application/pro_eng
    .ps application/postscript
    .psd application/octet-stream
    .pvu paleovu/x-pv
    .pwz application/vnd.ms-powerpoint
    .py text/x-script.phyton
    .pyc application/x-bytecode.python
    .qcp audio/vnd.qcelp
    .qd3 x-world/x-3dmf
    .qd3d x-world/x-3dmf
    .qif image/x-quicktime
    .qt video/quicktime
    .qtc video/x-qtc
    .qti image/x-quicktime
    .qtif image/x-quicktime
    .ra audio/x-pn-realaudio
    .ra audio/x-pn-realaudio-plugin
    .ra audio/x-realaudio
    .ram audio/x-pn-realaudio
    .ras application/x-cmu-raster
    .ras image/cmu-raster
    .ras image/x-cmu-raster
    .rast image/cmu-raster
    .rar application/vnd.rar
    .rexx text/x-script.rexx
    .rf image/vnd.rn-realflash
    .rgb image/x-rgb
    .rm application/vnd.rn-realmedia
    .rm audio/x-pn-realaudio
    .rmi audio/mid
    .rmm audio/x-pn-realaudio
    .rmp audio/x-pn-realaudio
    .rmp audio/x-pn-realaudio-plugin
    .rng application/ringing-tones
    .rng application/vnd.nokia.ringing-tone
    .rnx application/vnd.rn-realplayer
    .roff application/x-troff
    .rp image/vnd.rn-realpix
    .rpm audio/x-pn-realaudio-plugin
    .rt text/richtext
    .rt text/vnd.rn-realtext
    .rtf application/rtf
    .rtf application/x-rtf
    .rtf text/richtext
    .rtx application/rtf
    .rtx text/richtext
    .rv video/vnd.rn-realvideo
    .s text/x-asm
    .s3m audio/s3m
    .saveme application/octet-stream
    .sbk application/x-tbook
    .scm application/x-lotusscreencam
    .scm text/x-script.guile
    .scm text/x-script.scheme
    .scm video/x-scm
    .sdml text/plain
    .sdp application/sdp
    .sdp application/x-sdp
    .sdr application/sounder
    .sea application/sea
    .sea application/x-sea
    .set application/set
    .sgm text/sgml
    .sgm text/x-sgml
    .sgml text/sgml
    .sgml text/x-sgml
    .sh application/x-bsh
    .sh application/x-sh
    .sh application/x-shar
    .sh text/x-script.sh
    .shar application/x-bsh
    .shar application/x-shar
    .shtml text/html
    .shtml text/x-server-parsed-html
    .sid audio/x-psid
    .sit application/x-sit
    .sit application/x-stuffit
    .skd application/x-koan
    .skm application/x-koan
    .skp application/x-koan
    .skt application/x-koan
    .sl application/x-seelogo
    .smi application/smil
    .smil application/smil
    .snd audio/basic
    .snd audio/x-adpcm
    .sol application/solids
    .spc application/x-pkcs7-certificates
    .spc text/x-speech
    .spl application/futuresplash
    .spr application/x-sprite
    .sprite application/x-sprite
    .src application/x-wais-source
    .ssi text/x-server-parsed-html
    .ssm application/streamingmedia
    .sst application/vnd.ms-pki.certstore
    .step application/step
    .stl application/sla
    .stl application/vnd.ms-pki.stl
    .stl application/x-navistyle
    .stp application/step
    .sv4cpio application/x-sv4cpio
    .sv4crc application/x-sv4crc
    .svf image/vnd.dwg
    .svf image/x-dwg
    .svg image/svg+xml
    .svr application/x-world
    .svr x-world/x-svr
    .swf application/x-shockwave-flash
    .t application/x-troff
    .talk text/x-speech
    .tar application/x-tar
    .tbk application/toolbook
    .tbk application/x-tbook
    .tcl application/x-tcl
    .tcl text/x-script.tcl
    .tcsh text/x-script.tcsh
    .tex application/x-tex
    .texi application/x-texinfo
    .texinfo application/x-texinfo
    .text application/plain
    .text text/plain
    .tgz application/gnutar
    .tgz application/x-compressed
    .tif image/tiff
    .tif image/x-tiff
    .tiff image/tiff
    .tiff image/x-tiff
    .tr application/x-troff
    .ts video/mp2t
    .tsi audio/tsp-audio
    .tsp application/dsptype
    .tsp audio/tsplayer
    .tsv text/tab-separated-values
    .turbot image/florian
    .txt text/plain
    .uil text/x-uil
    .uni text/uri-list
    .unis text/uri-list
    .unv application/i-deas
    .uri text/uri-list
    .uris text/uri-list
    .ustar application/x-ustar
    .ustar multipart/x-ustar
    .uu application/octet-stream
    .uu text/x-uuencode
    .uue text/x-uuencode
    .vcd application/x-cdlink
    .vcs text/x-vcalendar
    .vda application/vda
    .vdo video/vdo
    .vew application/groupwise
    .viv video/vivo
    .viv video/vnd.vivo
    .vivo video/vivo
    .vivo video/vnd.vivo
    .vmd application/vocaltec-media-desc
    .vmf application/vocaltec-media-file
    .voc audio/voc
    .voc audio/x-voc
    .vos video/vosaic
    .vox audio/voxware
    .vqe audio/x-twinvq-plugin
    .vqf audio/x-twinvq
    .vql audio/x-twinvq-plugin
    .vrml application/x-vrml
    .vrml model/vrml
    .vrml x-world/x-vrml
    .vrt x-world/x-vrt
    .vsd application/x-visio
    .vst application/x-visio
    .vsw application/x-visio
    .w60 application/wordperfect6.0
    .w61 application/wordperfect6.1
    .w6w application/msword
    .wav audio/wav
    .wav audio/x-wav
    .wb1 application/x-qpro
    .wbmp image/vnd.wap.wbmp
    .web application/vnd.xara
    .webm video/webm
    .webp image/webp
    .wiz application/msword
    .wk1 application/x-123
    .wmf windows/metafile
    .wml text/vnd.wap.wml
    .wmlc application/vnd.wap.wmlc
    .wmls text/vnd.wap.wmlscript
    .wmlsc application/vnd.wap.wmlscriptc
    .word application/msword
    .woff font/woff
    .woff2 font/woff2
    .wp application/wordperfect
    .wp5 application/wordperfect
    .wp5 application/wordperfect6.0
    .wp6 application/wordperfect
    .wpd application/wordperfect
    .wpd application/x-wpwin
    .wq1 application/x-lotus
    .wri application/mswrite
    .wri application/x-wri
    .wrl application/x-world
    .wrl model/vrml
    .wrl x-world/x-vrml
    .wrz model/vrml
    .wrz x-world/x-vrml
    .wsc text/scriplet
    .wsrc application/x-wais-source
    .wtk application/x-wintalk
    .xbm image/x-xbitmap
    .xbm image/x-xbm
    .xbm image/xbm
    .xdr video/x-amt-demorun
    .xgz xgl/drawing
    .xif image/vnd.xiff
    .xl application/excel
    .xla application/excel
    .xla application/x-excel
    .xla application/x-msexcel
    .xlb application/excel
    .xlb application/vnd.ms-excel
    .xlb application/x-excel
    .xlc application/excel
    .xlc application/vnd.ms-excel
    .xlc application/x-excel
    .xld application/excel
    .xld application/x-excel
    .xlk application/excel
    .xlk application/x-excel
    .xll application/excel
    .xll application/vnd.ms-excel
    .xll application/x-excel
    .xlm application/excel
    .xlm application/vnd.ms-excel
    .xlm application/x-excel
    .xls application/excel
    .xls application/vnd.ms-excel
    .xls application/x-excel
    .xls application/x-msexcel
    .xlt application/excel
    .xlt application/x-excel
    .xlv application/excel
    .xlv application/x-excel
    .xlw application/excel
    .xlw application/vnd.ms-excel
    .xlw application/x-excel
    .xlw application/x-msexcel
    .xm audio/xm
    .xml application/xml
    .xml text/xml
    .xmz xgl/movie
    .xpix application/x-vnd.ls-xpix
    .xpm image/x-xpixmap
    .xpm image/xpm
    .x-png image/png
    .xlsx application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
    .xsr video/x-amt-showrun
    .xwd image/x-xwd
    .xwd image/x-xwindowdump
    .xyz chemical/x-pdb
    .yaml application/x-yaml
    .yml application/x-yaml
    .z application/x-compress
    .z application/x-compressed
    .zip application/x-compressed
    .zip application/x-zip-compressed
    .zip application/zip
    .zip multipart/x-zip
    .zoo application/octet-stream
    .zsh text/x-script.zsh
  9. 遇到了编译错误openFile: resource exhausted (Too many open files)我一开始并没有意识到这个是我系统默认文件打开总数是1024的关系。这个可以很容易解决: ulimit -n 5000 要是永远的改变需要修改这个文件:/etc/security/limits.conf nick hard nofile 5000

一月十三日 等待变化等待机会

  1. 我试图重现问题是怎么解决的,然后就明白了所谓的npm/component的安装。实际上是添加bin目录到bashrc,这个安装是基本的做法,我居然忘记了。
    1. 在aws上重开一个ubuntu的large的instance来实验,因为内存必须要大,我选择8G,而存储大小默认的8G不够,我选择了28G。
    2. 安装最最基本的工具git/npm:
      
      sudo apt-get install git npm cabal-install graphviz
      
    3. 安装Haskell,按照官方的安装指引
      
      curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh
      
      这个安装过程要求我预先安装以下包:
      sudo apt-get install build-essential curl libffi-dev libffi8ubuntu1 libgmp-dev libgmp10 libncurses-dev libncurses5 libtinfo5
      这个似乎是有些多余,不过无大碍。因为他们似乎仅仅是屏幕显示相关的吧?
      我发现这个官方安装的版本会有冲突,要使用cabal update来安装haskell。
    4. 安装ubuntu的graphviz。注意不要搞错了,这个不是npm的!!!否则你就一直有dot找不到的问题。而所谓的node-dot和这个完全无关,我费了好大劲儿才明白。大师的文档写的一清二楚!在上一步完成了。
    5. 要安装一些npm的组件:
      npm install split mathjax-full mathjax-node-sre
    6. 下载mathjax-node-cli
      
      git clone https://github.com/mathjax/mathjax-node-cli/
      echo "export PATH=\"$PWD/mathjax-node-cli/bin:\$PATH\"" >> ~/.bashrc && source ~/.bashrc 
      
  2. 我提给大师的所谓的issue不是很正确,被驳回了。

一月十五日 等待变化等待机会

  1. 折腾了一个晚上终于才明白所有的问题都在于ec2有一个所谓的secuirty-group的概念我没有,这个就是防火墙的规则,而我没有为此打开port,所以,怎么都不可以通讯!
  2. 我完全不知道为什么能够成功,完全是突然之间,就可以了,在早上我出门之前还不行,回来也许和instance重启有关系吗?
    1. 首先是这个ami(ami-0bcd06f1209545cd6)是openvpn公司或者社区创建的,它通过了aws/ec2来收取的一个费用。
    2. 它应该属于所谓的BYOL(Bring Your Own Licence)的范畴。这个文档很详细。这里的费用是两重的,首先,是软件公司卖的的证书,两个连接免费,其次是aws的ec2 instance的钱,对于我目前使用t2.micro价格是$0.014/hour。另一个费用是存储的费用General Purpose SSD (gp2) $0.12 of GB of provisioned storage per month我现在使用的是8G,所以一个月应该是8x$0.12=$0.96。所以,如果开一个月的话大约是11美元。我使用internet speed test,结果好几个没有结果,唯一的一个反映我的下载速度有500+M,这个速度的确是令人满意的。至少我看youtube非常的流畅应证了这一点。当然这个vpn肯定有些古怪的地方因为我的android手机,
    3. 一个最具体的实证就是查询我的IP显示的的确是我的ec2/openvpn的ip,当然你能够上谷歌也已经证明了这一点。我的想法是这个是通过DNS配合实现的,因为我之前就能够顺利连接我的vpn但是依旧不能访问谷歌的原因还是DNS的问题,因为这个和大公司使用vpn的情况不同,因为那个时候其实问题相对简单,你要访问的是内网IP,或者是防火墙/gateway后面不可见的地址,毫无疑义的你目前的运营商提供的DNS服务不会有问题,而我现在不是不能看到谷歌的IP,而是被GFW拦截了,这个不是在DNS出问题,那么你使用通常的运营商的路径就是死路一条。但是如何让我的OS知道我需要使用vpn自带的DNS服务呢?这个就是问题的核心,这个也是我遇到openvpn的文档里反复读到但是一直不得要领的地方:
      One major feature that is missing with the command line client is the ability to automatically implement DNS servers that are pushed by the VPN server. It is possible, but it requires you to install a DNS management program such as resolvconf or openresolv, and it may or may not clash with existing network management software in your OS. The idea here, however, is that you use a script that runs when the connection goes up, and when it goes down, that uses resolvconf or openresolv to implement the DNS servers for you. The reason why this client is not able to manage it completely by itself is mainly because in an operating system like Windows, Macintosh, Android, or iOS, there is already an established single method of handling DNS management. It is therefore easy for us to create a software client for those operating systems that already knows how to handle DNS. But Linux is available in so many variations and also supports different programs and methods of implementing DNS servers, and so it was only reasonable to leave built-in DNS support out of the OpenVPN program and instead to provide, where possible, a script that handles DNS implementation. Such a script could even be written by yourself to do whatever tasks are necessary to implement the DNS servers in your unique situation.
      我一直在想这个文档要表达什么意思呢?为什么要把DNS server推送给我们的client系统呢?
    4. 在aws/ec2上使用elastic ip是防止每次重启都要重新设置的关键,这个虽然很普通,但是也是我实践才意识到的,作为客户端获得的profile的配置是无法从ec2上自动探测它自己的ip地址的(至少我目前还不知道简单的办法),因为都是内网地址,因此产生的证书不会每次重启都去自动更新,也许这里还有一个cluster的机制吧,比如你创建的ec2是一个backup你当然不希望它改变?总之,要使用elastic ip才好。
    5. 这里的所谓的source-destination-check是aws的机制,和security-group不是一回事。

      If your VPN setup consists of a site-to-site setup between your cloud instances and your machines on-premises, ensure you disable source destination check protection on Amazon; otherwise, routing won’t function properly.

      Turn off source/destination checks:

      1. Right-click on the VPN instance
      2. Select Change Source/Dest.
      3. Check and make sure the status is Disabled.

      Source/destination checking can also block traffic if you want VPC data to go directly to the IP addresses of your VPN clients in the VPN client subnet. For that use case, turn off the check as well.

      这里所说的后一个use case,我还是不理解。总之,这个是我之前没有作的一个步骤,很可能是影响route的一个原因吧?
    6. 这里是重点,首先是为什么或者说是什么,因为这一点是vpn原理的一个核心,我之前始终不理解,作为vpnclient访问vpnserver是里所应当的,那么需要反过来吗?如果单单是网页浏览似乎没有必要吧?

      OpenVPN Access Server’s default routing uses network address translation (NAT). Traffic originating from the VPN clients appears to come from the local IP address of the Access Server with NAT, and this is simpler than setting up routing.

      However, when using NAT, your traffic from the VPC itself can’t directly access a VPN client as the NAT engine prevents direct contact. You must configure routing instead of NAT to allow direct access to a VPN client.

      那么不要NAT要routing,要怎么做呢?
      1. Sign in to the Admin Web UI.
      2. Click Configuration > VPN Settings.
      3. Scroll to the Routing section, where you can click Yes, using Routing.
      4. Configure your subnets for your network.
      这么作的结果是这样子的

      After setting up routing, the source IP address of packets coming from the VPN clients is kept intact, and direct access from the VPC network to the VPN client subnet is possible. However, because the VPC doesn’t automatically recognize the VPN subnet within the VPN instance, it doesn’t know how to send the return traffic back to the instance. To correct this problem, add a static route in the Amazon routing table for your VPC so that the return traffic flows properly. Refer to Amazon’s AWS VPC routing documentation: Route tables for your VPC (Amazon).

      最后一句实际上我还是看不懂,在ec2/vpc上的route难道aws已经自动作了吗?我看了半天也不理解。
    7. 在launch ec2的时候,你可以透过传递所谓的user data的方式设置一些openvpn的预设参数:
      Entering user data:

      1. During the steps above for creating an AMI, when you reach step 7, Advanced details, expand that section.
      2. Scroll down to the text field, User data.
      3. Enter your data for one or more of the available settings below. Ensure you enter each row as key1=value1, and don’t use quote keys or spaces on either side of the equal character.
      这里有两个我很感兴趣的部分:
      Key Description
      reroute_gw (boolean, default=0) If 1, clients route internet traffic through the VPN.
      reroute_dns (boolean, default=0) If 1, clients route DNS queries through the VPN. Note: If the VPC CIDR block is defined, it is made accessible to VPN clients via NAT.
    8. 目前遇到的另一个问题是在firefox可以使用,但是在chromium里似乎openvpn的配置不起作用,为什么?
    9. 在我本地如果使用nslookup看到的谷歌的ip和在openvpn上看到的是不一样的。这个当然是可以理解的,那么由此引发的不同的traceroute结果也是可以理解的,那么从两地达到同一个目的地的路线也是可以理解的。那么有什么结果可以总结的呢?
    10. 总而言之,有一个openvpn的设置是很重要的,就是要Should client Internet traffic be routed through the VPN?设定为Yes
    11. 看到另一个我不明白的地方,就是ubuntu似乎是使用所谓的resolvectl来解释域名吧?这个似乎不认同新创建的软设备如我们的tunnel,而且它解释的谷歌的地址和nslookup不一样不知道怎么回事现在所有resolvectl/dig/nslookup返回的结果都是一致的了。难道改变了什么?在我启动openvpn客户端后能够看到routing table的变化,那么这个应该不应该被chromium-browser设置呢?
      
      dig +short www.google.com
      nslookup www.google.com
      resolvectl query -4 www.google.com
      
      这三个命令得到的结果现在看来是一致的。
  3. 静夜思
    斜月三星伴,
    意马心猿牵。
    万里相思刻,
    灵台方寸间。
    

一月十八日 等待变化等待机会

  1. 我找到了一个制作或者说是复制现有的ami的过程,我对此还是不太相信,至少这个只是一半的流程。 我需要准备好我的证书和私钥,以及我的账号,然后调用ec2-ami-tools的命令:sudo ec2-bundle-vol --no-inherit -k private/key/path -c certificate/path -u my-aws-uid -d /dest/path
  2. 卡在qemu的bridge network上,我看这个也许有些希望。之前我已经可以使用ubuntu的安装iso来创建一个虚拟机了。
  3. 创建磁盘qemu-img create mydisk.img 10G然后就是运行安装iso,qemu-system-x86_64 -boot d -cdrom /dev/cdrom -m 2G -hda mydisk.img,安装之后就直接运行磁盘。
  4. 最后还是这个最最靠谱,因为,这个正如作者说的那样就是一个最最简单的方法,当然我之前不成功也许是某些操作或者之前的操作的干扰?
    1. sudo mkdir /etc/qemu; echo "allow virtbr0" | sudo tee /etc/qemu/bridge.conf
      但是我还是有些不解的是这个是qemu创建需要用到的吗?
    2. sudo chmod +s /usr/lib/qemu/qemu-bridge-helper
      我之前一直有acl的错误,我不知道这个是不是需要apparmor之类的pan的权限控制,总之,这个似乎在我七搞八搞重启服务之后解决了。
    3. 创建这个bridge分配ip是我当前的host机的,这个会不会有什么问题呢?有些博主是靠dhclient来作的,有些不太可靠。
      
      sudo brctl addbr virtbr0
      sudo brctl addif virtbr0 enp0s31f6
      sudo ip addr add 192.168.1.23/24 dev virtbr0
      sudo ip link set virtbr0 up
      
    4. sudo iptables -I FORWARD -m physdev --physdev-is-bridged -j ACCEPT
      对于这个我始终是将信将疑,我刚刚还在担心结果网卡就挂了。
    5. 启动qemu的时候使用这个参数:
      qemu-system-x86_64 -boot d -m 2G -hda serverdisk.img -enable-kvm -net nic,model=virtio,macaddr=52:54:00:00:00:01 -net bridge,br=virtbr0
      
      那个mac地址无所谓的,只要不冲突都行。
    6. 我觉得我之前设立openvpn之所以能够成功的原因就在于routing-table里第一个解析必须要通过我的vpn才行:
      
      nick@nick-sager:~/ami$ route
      Kernel IP routing table
      Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
      0.0.0.0         172.27.232.1    128.0.0.0       UG    0      0        0 tun0
      default         192.168.1.1     0.0.0.0         UG    100    0        0 enp0s31f6
      ec2-54-67-3-66. 192.168.1.1     255.255.255.255 UGH   0      0        0 virtbr0
      128.0.0.0       172.27.232.1    128.0.0.0       UG    0      0        0 tun0
      link-local      0.0.0.0         255.255.0.0     U     1000   0        0 enp0s31f6
      172.27.232.0    0.0.0.0         255.255.248.0   U     0      0        0 tun0
      192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 virtbr0
      192.168.1.0     0.0.0.0         255.255.255.0   U     100    0        0 enp0s31f6
      192.168.1.0     0.0.0.0         255.255.255.0   U     425    0        0 virtbr0
      
      成也萧何,败也萧何,如今我要创建bridge似乎就在分配ip上有问题吧?
    7. 经过短暂的欢呼我遇到了地址冲突的问题,我不确定是不是我的虚拟机直接和我的笔记本在争夺控制权呢?

一月二十日 等待变化等待机会

  1. 我枉费心计想要达到的目的是如此的简单以至于没有人会想到这么的幼稚。当你运行虚拟机的时候,对于guest OS来说访问外界网络是一个基本的必须,而且早就作的妥妥的,而大多数所需要的是从host OS去访问guest OS,这个通常是不那么必须的,所以,才费了很大的功夫来设定bridge。而我的需求甚至于直接使用serial console就能够达到。总而言之,我再次审视我的qemu的虚拟机发现它可以很方便的访问host OS,比如它的ip是10.0.2.3,而网关是10.0.2.1,而我自己的笔记本就是hostOS就是10.0.2.2,这是一个多么简单的问题啊!
  2. 我使用ec2-upload-bundle总是遇到curl的cacert的错误,茫然不知所措,只是知道这个并非是我的问题,最后发现还是我安装默认的ubuntu的ec2-ami-tools的版本太低了,改成了直接安装最新版本才得到解决。
    
    	sudo apt-get update -y && sudo apt-get install -y ruby unzip
    wget https://s3.amazonaws.com/ec2-downloads/ec2-ami-tools.zip
    sudo mkdir -p /usr/local/ec2
    sudo unzip ec2-ami-tools.zip -d /usr/local/ec2
    
    然后是环境设置在.bashrc的做法:
    
    export EC2_AMITOOL_HOME=/usr/local/ec2/ec2-ami-tools-1.5.19
    export PATH=$EC2_AMITOOL_HOME/bin:$PATH
    
    检验安装结果:ec2-ami-tools-version
  3. 有些问题是出奇的寻常,但是我确实脑子里模糊了。比如你要创建一个ami,那么它的image要存在哪里呢?很明显的你要附带的mount一个新的volume,这不是很通常的想法吗?所以,要qemu-image去再创建一个磁盘,然后运行的时候把它作为-hdb的硬盘加载。可是文件系统没有格式化,所以,这里要一步一步的创建:
    1. Determine Drive Information:
      sudo lshw -C disk
  4. Partition The Disk
    
    sudo parted /dev/sdb
    
    
  5. 1) Start parted as follows:

    sudo parted /dev/sdb

    2) Create a new GPT disklabel (aka partition table):

    (parted) mklabel gpt

    3) Set the default unit to TB:

    (parted) unit TB

    4) Create one partition occupying all the space on the drive. For a 4TB drive:

    (parted) mkpart
    Partition name?  []? primary
    File system type?  [ext2]? ext4
    Start? 0
    End? 4

    Alternatively, you can set the partition size as a percentage of the disk. To create a partition occupying all the space on the drive:

    (parted) mkpart
    Partition name?  []? primary
    File system type?  [ext2]? ext4
    Start? 0%
    End? 100%

    5) Check that the results are correct:

    (parted) print

    There should be one partition occupying the entire drive.

    6) Save and quit "parted":

    (parted) quit
  6. 但是我其实用fdisk比较多,而这个前提实际上并不是很清楚,这里写的就很清楚,如果我不在乎它只有一个partition,不在乎其他操作系统来使用,那么直接使用fdisk就可以创建磁盘文件系统了,因为我只是拿它作为一个临时存储而已。
    
    sudo fdisk /dev/sdb 
    
    然后直接 sudo mkfs -t ext4 /dev/sdb1 说来惭愧,这么多年来我始终对于分区表以及文件系统有着似是而非的认识,即便以前经常使用但依旧概念模糊,手法生疏,可耻啊。
  7. 我已经十几年没有正经使用aws了,结果就是cli必须要更新了。当然首先是要卸载ubuntu的官方的旧版本。
    
    curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
    unzip awscliv2.zip
    sudo ./aws/install
    
    配置又是一大堆的工作要作!先歇一下吧。
  8. 关于aws ec2的instance所对应的root device type也是一个很头疼的,如果我不是有一点点概念肯定就又卡壳了。
    Only the following instance types support an instance store volume as the root volume: C3, D2, G2, I2, M3, and R3.
    我发现实际上自己制作ebs-ami是一件很麻烦的事情,我决定放弃了。

一月二十二日 等待变化等待机会

  1. 我决定转移战场,因为实际上有需求的还是当初的stable-diffusion的项目。因为没有vpn而要修改github真的是很烦人的。那么
    1. git clone --recursive https://github.com/AUTOMATIC1111/stable-diffusion-webui.git
    2. 直接运行./webui.sh会有Torch is not able to use GPU不能用的错误。于是我尝试先安装torch:
      
      pip install torch torchvision
      
    3. 以上并不能解决,似乎torch需要使用cuda来操纵gpu,那么安装cuda吧?
      sudo apt-get install nvidia-cuda-dev python3-pycuda
    4. 依旧解决不了,看看这个看行不行。 其中
      pip install git+https://github.com/crowsonkb/k-diffusion.git --prefer-binary
      看样子不能直接使用binary,去掉--prefer-binary重新编译。结果编译还是出错,再次重试。。。

      类似的

      pip install git+https://github.com/TencentARC/GFPGAN.git --prefer-binary
      去掉--prefer-binary重新编译。

      似乎这个module没有安装
      pip install pytorch_lightning
      而能够看到这个错误是直接运行python webui.py而不是运行那个webui.sh

      类似的要安装gradio

    5. 遇到sgm模块找不到只好
      
      git clone https://github.com/Stability-AI/generative-models.git repositories/generative-models
      
      这个似乎没有完成,因为我看到README.md里说了安装步骤:
      1. Clone the repo
        
        git clone https://github.com/Stability-AI/generative-models.git repositories/generative-models
        cd generative-models
        
      2. 
        python3 -m venv .pt2
        source .pt2/bin/activate
        pip3 install -r requirements/pt2.txt
        
      3. install sgm
        
        pip3 install .
        
      4. install sdata for training
        
        pip3 install -e git+https://github.com/Stability-AI/datapipelines.git@main#egg=sdata
        
      5. packaging:
        
        pip install hatch
        hatch build -t wheel
        
        然后
        pip install dist/*.whl
      6. 遇到了这个错误:ModuleNotFoundError: No module named 'pytorch_lightning.utilities.distributed' 这个看起来是一个笔误,把所谓的

        Tried something else, as well. there are a series of errors due to pytorch_lightning.utilities.distributed in

        1. /stable-diffusion-webui/repositories/stable-diffusion-stability-ai/ldm/models/diffusion/ddpm.py (Line: 20)
        2. /stable-diffusion-webui/extensions-builtin/LDSR/sd_hijack_ddpm_v1.py (Line: 17)

        In both the files, just change pytorch_lightning.utilities.distributed to pytorch_lightning.utilities.rank_zero at above stated lines. And the issues will be resolved.

        It worked for me. Might work for you as well.

      7. 对于ModuleNotFoundError: No module named 'taming'
    6. open_clip模块找不到需要pip install open_clip_torch

一月二十五日 等待变化等待机会

  1. 折腾了很久又被俗世打断。今天重新审视感觉没有安装好cuda是第一个问题。因此,这里先下载各种包吧? 而这里是所有相应的cuda包的列表。
    Table 5 Meta Packages Available for CUDA 12.3

    Meta Package

    Purpose

    cuda

    Installs all CUDA Toolkit and Driver packages. Handles upgrading to the next version of the cuda package when it’s released.

    cuda-12-3

    Installs all CUDA Toolkit and Driver packages. Remains at version 12.3 until an additional version of CUDA is installed.

    cuda-toolkit-12-3

    Installs all CUDA Toolkit packages required to develop CUDA applications. Does not include the driver.

    cuda-toolkit-12

    Installs all CUDA Toolkit packages required to develop applications. Will not upgrade beyond the 12.x series toolkits. Does not include the driver.

    cuda-toolkit

    Installs all CUDA Toolkit packages required to develop applications. Handles upgrading to the next 12.x version of CUDA when it’s released. Does not include the driver.

    cuda-tools-12-3

    Installs all CUDA command line and visual tools.

    cuda-runtime-12-3

    Installs all CUDA Toolkit packages required to run CUDA applications, as well as the Driver packages.

    cuda-compiler-12-3

    Installs all CUDA compiler packages.

    cuda-libraries-12-3

    Installs all runtime CUDA Library packages.

    cuda-libraries-dev-12-3

    Installs all development CUDA Library packages.

    cuda-drivers

    Installs all Driver packages. Handles upgrading to the next version of the Driver packages when they’re released.

  2. 但是我发现还是最好使用ubuntu官方的包,否则冲突是不可避免的。所以,先卸载旧的包。 sudo apt-get purge libnvidia-compute-510 libnvidia-compute-525 libnvidia-compute-525:i386 libnvidia-ml-dev 然后使用官方的所谓的p类型的包:aptitude search '~P cuda-'
  3. 遇到各种各样的奇怪的问题,时不时的openvpn不工作,另一个奇怪的问题就是ssh到aws的ubuntu为什么不能够正常的x11呢?似乎不是openvpn的问题。并且我发现似乎我使用的免费的openvpn的配置的google等的网址居然使用了facebook的域名,或者说 PING www.google.com(edge-star-mini6-shv-01-vie1.facebook.com (2a03:2880:f107:83:face:b00c:0:25de)) 56 data bytes 这个让我有些毛骨悚然,也许这个openvpn免费的东西是在把我引流到某个广告引擎,甚至是黑客的过滤网站?然后启动web.sh的时候注意到一个git的option居然没有--refetch,然后我才意识到开发者们使用的是高版本的git,我默认的ubuntu22.04的版本太老了。
  4. 然后我就发现是自己的愚蠢造成的问题,我之前发现了一个问题,就照着网络上的修改,改了一个东西,然后没有提交的状态下git无法正常的更新导致错误。 在repositories/stable-diffusion-stability-ai/ldm/models/diffusion/ddpm.py里有一个
    
    diff --git a/ldm/models/diffusion/ddpm.py b/ldm/models/diffusion/ddpm.py
    index bbedd04..ef0990e 100644
    --- a/ldm/models/diffusion/ddpm.py
    +++ b/ldm/models/diffusion/ddpm.py
    @@ -16,7 +16,7 @@ from contextlib import contextmanager
     from functools import partial
     from tqdm import tqdm
     from torchvision.utils import make_grid
    -from pytorch_lightning.utilities.distributed import rank_zero_only
    +from pytorch_lightning.utilities.rank_zero import rank_zero_only
     
     from ldm.util import log_txt_as_img, exists, default, ismap, isimage, mean_flat, count_params, instantiate_from_config
     from ldm.modules.ema import LitEma
    
    我只能希望新版本修正这个问题???
  5. 似乎安装是没有问题了,然后遇到了第一次运行需要checkpoint的问题。这里我需要下载所谓的.ckpt文件然后放在models/Stable-diffusion目录下。
  6. 我找到了这个指南,这里介绍了最流行的models。。
  7. 这是keywords的列表

    Medium

    Medium defines a category of artwork.

    keywordNote
    PortraitVery realistic drawings. Good to use with people.
    Digital paintingDigital art style.
    Concept artIllustration style, 2D.
    Ultra realistic illustrationDrawings that are very realistic. Good to use with people.
    Underwater portraitUse with people. Underwater. Hair floating.
    Underwater steampunkVery realistic drawings. Good to use with people.

    Style

    These keywords further refine the art style.

    keywordNote
    hyperrealisticIncreases details and resolution
    pop-artPop-art style
    Modernistvibrant color, high contrast
    art nouveauAdd ornaments and details, building style

    Artist

    Mentioning the artist in the prompt is a strong effect. Study their work and choose wisely.

    keywordNote
    John Collier19th century portrait painter. Add elegancy
    Stanley Artgerm LauGood to use with woman portrait, generate 19th delicate clothing, some impressionism
    Frida KahloQuite strong effect following Kahlo’s portrait style. Sometimes result in picture frame
    John Singer SargentGood to use with woman portraits, generate 19th delicate clothing, some impressionism
    Alphonse Mucha2D portrait painting in style of Alphonse Mucha

    Website

    Mentioning an art or photo site is a strong effect, probably because each site has its niche genre.

    keywordNote
    pixivJapanese anime style
    pixabayCommercial stock photo style
    artstationModern illustration, fantasy

    Resolution

    keywordNote
    unreal engineVery realistic and detailed 3D
    sharp focusIncrease resolution
    8kIncrease resolution, though can lead to it looking more fake. Makes the image more camera like and realistic
    vray3D rendering best for objects, landscape and building.

    Additional details

    Add specific details to your image.

    keywordNote
    dramaticshot from a low angle
    silkAdd silk to clothing
    expansiveMore open background, smaller subject
    low angle shotshot from low angle
    god rayssunlight breaking through the cloud
    psychedelicvivid color with distortion

    Color

    Add an additional color scheme to the image.

    keywordNote
    iridescent goldShinny gold
    silverSilver color
    vintagevintage effect

    Lighting

    keywordNote
    rim lightinglight on edge of an object
    cinematic lightingA generic term to improve contrast by using light
    crepuscular rayssunlight breaking through the cloud

一月二十七日 等待变化等待机会

  1. 不要还没学会走路就想跑!还是从第一步如何产生合适的prompt开始吧。
    1. Subject (required)
    2. Medium
    3. Style
    4. Artist
    5. Website
    6. Resolution
    7. Additional details
    8. Color
    9. Lighting
    10. 所谓的AIGC是画鬼最易,那么画真人才难。无怪话现代艺术都要走抽象派,印象派,逃避现实是最容易的解决方案。这里介绍了一个技巧就是可以使用名人的脸来作参考,当然这里要使用英文名字,拼音也行,比如我们可以创造一个范冰冰的脸孔:
      photo of young woman, [fan bingbing:0.96], highlight hair, sitting outside restaurant, wearing dress, rim lighting, studio lighting, looking at the camera, dslr, ultra quality, sharp focus, tack sharp, dof, film grain, Fujifilm XT3, crystal clear, 8K UHD, highly detailed glossy eyes, high detailed skin, skin pores
      我感觉AI是先产生了一个女人在酒吧的图片然后再换脸,这个可以似乎是我看到webui产生缩略图的步骤这么猜测的。这里是negative prompt
      disfigured, ugly, bad, immature, cartoon, anime, 3d, painting, b&w
      当然这里还可以把两个名人的名字串在一起搞出一个混合的脸。 但是这个完全取决于模型,我发现似乎prune的模型不再认识名人的脸了。
    11. 这个civitai.com有不少的模型,还有些似乎是使用别人的模型创建的模型,似乎就是一些prompt的集合?我不确定。总之这个领域是非常的兴旺繁荣的。
    12. 下载了一个名人的包,就是.pt的文件,按照指示,这个是要放在embedding目录下,然后当提示的关键字出现就可以了。

一月二十九日 等待变化等待机会

  1. 第一次录屏等于是学习总结如何使用inpaint来修图,这个以前在使用photoshop是一个很大的工程,如今对于一个门外汉只是几分钟的工作,而且超越了普通美工的水平了。
  2. 现在探索下一步,视频如何玩,我还是一无所知,面对ali的这个模型我甚至不知道要怎么安装,它不是针对初学者的。我想先尝试这个看上去更加成熟的模型
  3. 这里是UAE的一个基本介绍
    1. 首先,UAE是什么?Variational AutoEncoder就是:
      A variational autoencoder (VAE) is a technique used to improve the quality of AI generated images you create with the text-to-image model Stable Diffusion. VAE encodes the image into a latent space and then that latent space is decoded into a new, higher quality image.
      就是说它是一个提高图像质量的工具。什么是latent space呢?未知的?隐含的?让我想起了WarCraft里的咒语:From light to darkness. From darkness to light.
    2. 这里解释说latent space是一个a lower-dimensional representation of the image
      There are two main types of VAEs that can be used with Stable Diffusion: exponential moving average (EMA) and mean squared error (MSE). EMA is generally considered to be the better VAE for most applications, as it produces images that are sharper and more realistic. MSE can be used to produce images that are smoother and less noisy, but it may not be as realistic as images generated by EMA.
    3. 如何使用才是最实用的:

      To use VAE with Stable Diffusion, you will need to download a VAE model and place it in the stable-diffusion-webui/models/VAE directory. You can then select the VAE model that you want to use in the Settings > Stable Diffusion > SD VAE

    所以,我的理解就是VAE是一个后期提高画质的工具,但是我并不是直接使用,而是model或者说是checkpoint自动加载使用的,我只需要设置选择就可以了。所以,我之前看到阿里的txt2video并不是一个完全依靠VAE就能工作的。一定是辅助的。
  4. 偶然看到关于ssd常识的说明,我对于nvme是不是ssd始终不是很清楚。现在理解就是nvme是一个泛指的存储方式或者说协议?看来理解力有问题。我懒得读了。stable-diffusion的文档都读不过来。

一月三十日 等待变化等待机会

  1. 其实很多时候最难的是那些已经入门的人认为理所当然不言而喻的最最基本的问题。因为往往没有人会指出,或者不屑于指出,或者觉得说这些babytalk太掉价。而我需要这类的基本指引。比如怎么安装一个extension呢?到底我直接把它科隆到extensions的目录下面就自动安装了吗?不大可能的。后来我看到一个提示是在webui的extension上有一个install from URL,不知道这个是不是自动安装,但是至少我看到它是先科隆到repositories下,至于是否有通用的安装脚本我就不确定了。
  2. 我不知道extension是否成功安装,因为我的目的是text2video,这里我看大概有这么三条路径:
    1. AnimateDiff
      AnimateDiff is a text-to-video module for Stable Diffusion. It was trained by feeding short video clips to a motion model to learn how the next video frame should look like. Once this prior is learned, animateDiff injects the motion module to the noise predictor U-Net of a Stable Diffusion model to produce a video based on a text description.
      目前还不理解,先抄笔记再说。这里的结论是说视频的生成完全取决于模型,这个比较好理解,就是和文字图像没有本质区别的的方式,You can use AnimateDiff with any Stable Diffusion checkpoint model and LoRA. 安装步骤
      1. Start AUTOMATIC1111 Web-UI normally.
      2. Navigate to the Extension Page.
      3. Click the Install from URL tab.
      4. Enter the following URL in the URL for extension’s git repository field.
      5. https://github.com/continue-revolution/sd-webui-animatediff
      6. Wait for the confirmation message that the installation is complete.
      7. Download the AnimateDiff motion models and save it in stable-diffusion-webui > extensions > sd-webui-animatediff > model folder.

        Direct download link for v1.5 v2 motion model:

        https://huggingface.co/guoyww/animatediff/resolve/main/mm_sd_v15_v2.ckpt

        Direct download link for v1.4 motion model:

        https://huggingface.co/guoyww/animatediff/resolve/main/mm_sd_v14.ckpt

        Direct download link for v1.5 motion model:

        https://huggingface.co/guoyww/animatediff/resolve/main/mm_sd_v15.ckpt

        似乎这些是旧版本了。
      8. Restart Web-UI.
      从这看起来它仅仅是一个txt2img的一个拓展,比如怎样生成多幅图片的机制使用训练的模型,所以使用起来还是txt2img的界面。

      To use AnimateDiff in AUTOMATIC1111, navigate to the txt2img page. In the AnimateDiff section,

      • Enable AnimateDiff: Yes
      • Motion Module: There are two motion modules you can choose from. The v1.4 model creates more motion, but the v1.5 model creates clearer animations.

      Then write a prompt and a negative prompt as usual. For example

      prompt 1girl, looking at viewer, anime, cherry blossoms
      negative prompt disfigured, deformed, ugly
      似乎要配合这个动画的model才行? 这里是很多的动画的model 这里是使用指南因为我运行了一次后就在webui找不到了
    2. ModelScope
    3. Deforum
  3. 看来哪怕是最容易的video也要比image复杂上百倍。这里是基本的指引。
    1. 什么?

      AnimateDiff turns a text prompt into a video using a Stable Diffusion model. You can think of it as a slight generalization of text-to-image: Instead of generating an image, it generates a video.

    2. 怎么?这个就复杂了完全是另一篇的文章。我觉得核心的理解就是这个conditioning

      AnimateDiff uses a control module to influence a Stable Diffusion model. It is trained with a variety of short video clips. The control module conditions the image generation process to produce a series of images that look like the video clips it learns.

      我觉得另一个核心概念是controlNet:

      Like ControlNet, the control module of AnimateDiff can be used with ANY Stable Diffusion model. Currently, only Stable Diffusion v1.5 models are supported.

    3. 缺点或者说局限性: 简单:

      Since it follows the motion learned from the training data, it produces a generic motion that’s typically seen. It won’t produce a video that follows a detailed sequence of motions in the prompt.

      不可能有过多的创造想象的成分,不大可能造出没有见过的。
      The quality of motion is sensitive to the training data. It can’t animate exotic graphics that is not present in the training data.
    4. 窍门:
      1. Change the prompt during video generation. This technique is called prompt travel.
      2. Use a reference video with ControlNet.
    5. 这些都在以惊人的速度更新,之前的模型似乎已经过时了,作者这里有所有的新旧模型是否有冲突呢?
    6. 关于使用,作者建议使用这个模型cyberrealistic,但是这个似乎仅仅是一个prompt的模型?不,它是一个embedding。这里是安装指导
      Embedding, also called textual inversion, is an alternative way to control the style of your images in Stable Diffusion.
      就是说重定义?
      Embedding is the result of textual inversion, a method to define new keywords in a model without modifying it. The method has gained attention because its capable of injecting new styles or objects to a model with as few as 3 -5 sample images.
      就是说它不是模型,而是重定义旧的模型,这个工作量很小,仿佛思想钢印里打错一个真与假的符号就完全改变了信仰。
      The amazing thing about textual inversion is NOT the ability to add new styles or objects — other fine-tuning methods can do that as well or better. It is the fact that it can do so without changing the model.
      去哪里找呢?

      The go-to place to download embeddings is Civitai. Filter with textual inversion to view embeddings only.

      Hugging Face hosts the Stable Diffusion Concept Library, which is a repository of a large number of custom embeddings.

      总之,它是一些.bin文件要放在embedding目录下。它是使用文件名作为提示符号的。启动时候可以看到加载信息。
  4. 我折腾了半天也不知道为什么。我从webui里不能访问awailable extension: https://raw.githubusercontent.com/AUTOMATIC1111/stable-diffusion-webui-extensions/master/index.json 我尝试从命令行的确被拒绝了,我怀疑是vpn的问题,于是尝试curl/wget就发现同样的问题,使用nslookup raw.githubusercontent.com看到的是0.0.0.0,我怀疑这个是dns的设置问题。我尝试修改NetworkManager上的dns server ip。还安装bind9/dnsutil之类ubuntu的工具来手动修改。也许dns需要forward,总之过了好一会才有效果。这个和我启动webui.sh脚本应该是无关的。
  5. 然后安装extension重启遇到不兼容问题,这个解决了所有的问题:
    
    pip install --upgrade setuptools
    
    随后你运行
    
    pip install -r requirements.txt
    
    就看不到错误了。
  6. 始终看到什么TMalloc的问题,是要安装gperf库才行。
  7. 我终于开始明白一点我的UI的设置是在ui-config.json里定义的。但是这个似乎没有变化?同时大家普遍使用webui-user.sh来定制参数,一些设置都是为了防止不断升级带来的问题。
  8. 那么且把ui-config的问题放一边,不要太激进,从更容易的img2video来看看。这个实际上是一个更加成熟的步骤。就是我反复看到的所谓的svd。
    Stable Video Diffusion (SVD) Image-to-Video is a diffusion model that takes in a still image as a conditioning frame, and generates a video from it.
    所以,它的核心还是conditioning。我决定从webui直接安装这个不是所谓的extension,所以,不能安装,而且install from URL需要的是git不是huggingface这类的文件发布方式。
  9. 且慢,从源头来看这个是去年发行的这个generative-models来的。我要从源头看看。

    首先,安装就是很有意思。我感觉python和java一样非常复杂的运行环境,所以,使用所谓的虚拟环境很重要。

    1. 
      git clone https://github.com/Stability-AI/generative-models.git
      cd generative-models
      
    2. 
      # install required packages from pypi
      python3 -m venv .pt2
      source .pt2/bin/activate
      pip3 install -r requirements/pt2.txt
      
    3. pip3 install .
    4. 
      pip3 install -e git+https://github.com/Stability-AI/datapipelines.git@main#egg=sdata
      

    遇到fairscale安装总是失败的问题,那么就提前安装一下吧。实在是不行还有从源码安装的选项。
    
    git clone https://github.com/facebookresearch/fairscale.git
    cd fairscale
    pip install -r requirements.txt
    # -e signified dev mode since e stands for editable
    pip install -e .
    
    这里的packaging对于我是没有用的吧?我需要吗?我一点概念都没有。我是使用模型还是训练模型呢?
    
    pip install hatch
    hatch build -t wheel
    
    这里的inference是训练模型吗?
  10. 我这几天的折腾发现这个领域熟悉python比熟悉其他都来的重要,而这方面我又是几乎零起步。
  11. 这里又是另一个我不理解的东西,什么是streamlit,似乎是一个demo?demo什么呢?这里是文档
    Streamlit is an open-source Python library that makes it easy to create and share beautiful, custom web apps for machine learning and data science. In just a few minutes you can build and deploy powerful data apps. So let's get started!
    所以,它是一个python的库,可以作非常令人震惊的app应用,我看它的hello demo简直完全不知道它是怎么做出来的。这个是完全偏离了ai的部分,但是它非常的强大,以至于对于大量数据需要展示的应用的制作应该是非常的有用,我不知道它是怎么作出那些漂亮的统计图表,简直就是行走的office应用。
  12. 什么是git-lfs呢?原理是什么呢?我要怎么使用呢?
  13. 今天是混乱的一天,我完全没有什么成就感,因为安装txt2video根本不能工作甚至于之前还能看到的ui-tab也消失了。完全不能理解。
  14. 有时候撤退是为了更好的进攻,我觉得我完全没有能力学习video,所以,先回到最基本的模型来吧。 Fine-tuned models
    Fine-tuning is a common technique in machine learning. It takes a model trained on a wide dataset and trains a bit more on a narrow dataset.
    简而言之,就是回锅肉。人们之所以要训练fine-tuned,就是因为原本的大模型广而不精。

    这个是SDXL模型

  15. 我终于找到我的问题原因了,在extension界面里有一个禁止所有extension的选项,我必须打开animatediff,不过随后我就遇到了致命的显卡显存不足的问题!这个就是我之前放弃的原因。显卡显存只有6G怎么办?有人建议优化
    export COMMANDLINE_ARGS="--opt-split-attention --opt-sub-quad-attention --lowvram"
    这个设在webui-user.sh里,看来最后一个应该是起作用的。
  16. 但是最后不能存成mp4或者gif,我看到--disable-safe-unpickle,但是作者说还是创建新的安全模型更好。这个方法,不知道行不行。 似乎是可以了,不过要记住生成的文件是在outputs目录下的一个Animatediff目录下。以下就是这个教程的结果。
  17. 稍微修改了一下prompt:
    ((best quality)), ((masterpiece)), ((realistic)), long highlighted hair,  (fan bingbing:0.95), Asian girl in red Chinese ancient armor, confident stance, high-resolution, living room, smiling, head tilted
    negative prompt依然是CyberRealistic_Negative-neg然后产生的这个结果: 而在img2img里选择这个motion module其实是相当关键的,因为在没有这个模型之前产生的图像变化很大,作出的视频还是gif都是巨大的跨越导致人眼看起来很不舒服。这里就是模仿范冰冰的视频和动画: 制作了一个简单的录频加以记录。

一月三十一日 等待变化等待机会

  1. 通过昨天的密集的学习应该是有些入门了,毕竟这个本来就是对于计算机小白都能掌握的,主要的用户人群实际上是美工和艺术家们。无论如何对于这个模型的入门介绍还是非常有价值的。而这个快速入门指导也是有意义的。
  2. 在开始其他两种视频途径之前,我想先学习一下各个模块,比如controlNet,这个我久闻大名,一直不明白。
    1. 什么?
      ControlNet is a neural network that controls image generation in Stable Diffusion by adding extra conditions.
      这个是原始论文的出处。我下载了一份备份
    2. 能做什么?
      • Specify human poses.
      • Copy the composition from another image.
      • Generate a similar image.
      • Turn a scribble into a professional image.
    3. 这个定义是更加详细的:

      ControlNet is a neural network model for controlling Stable Diffusion models. You can use ControlNet along with any Stable Diffusion models.

      而这里的核心又是conditioning,这里有一个更加深刻的定义:就是通过改变noise predictor,这个是什么我还不清楚,但是有个概念也好。
      The purpose of conditioning is to steer the noise predictor so that the predicted noise will give us what we want after subtracting from the image.
      我发现这个是整个工作机制的最好的介绍,但是我现在还没有能力一个个消化。
    4. ControlNet adds one more conditioning in addition to the text prompt. The extra conditioning can take many forms in ControlNet.
      ControlNet本身是一种额外的conditioning,是在原有的text prompt基础上的。作者举了两个实例来说明:
      Controlling image generation with (1) edge detection and (2) human pose detection.
    5. 第一种是edge detection,这个图非常的形象生动:
      ControlNet takes an additional input image and detects its outlines using the Canny edge detector. An image containing the detected edges is then saved as a control map. It is fed into the ControlNet model as an extra conditioning to the text prompt.
      能不能说controlNet需要图文并茂来给模型作提示,连说带比划
    6. 这个过程的更加专业的描述是
      The process of extracting specific information (edges in this case) from the input image is called annotation (in the research article) or preprocessing (in the ControlNet extension).
      图形轮廓是annotation,或者是脚注。而在controlNet内部是所谓的预处理。这些都是高级的概念,我听听就好。
    7. 在我看来第二种human pose detectionedge detection也许就是更加偏重于以人物为对象吧?
      Edge detection is not the only way an image can be preprocessed. Openpose is a fast human keypoint detection model that can extract human poses like positions of hands, legs, and head. See the example below.
      这里又提到了它内部使用的机制是一个什么openPose,人工智能的链条极其的长,任何一个环节都是无数人的心血劳动努力。
    8. 抄笔记本身就是学习的过程,抄一遍至少有一个印象:
      Below is the ControlNet workflow using OpenPose. Keypoints are extracted from the input image using OpenPose, and saved as a control map containing the positions of key points. It is then fed to Stable Diffusion as an extra conditioning together with the text prompt. Images are generated based on these two conditionings.
      我称之为精读 这里是一个从图像到语言,又从语言到图像的过程。又一次让我想起了:From light to darkness; From darkness to light;这个是符合马克思主义唯物辩证法关于人类认识世界改造世界的过程的一般论述的。就是从具体到抽象,再从抽象到具体。这个就是人眼识别的一般做法。 这里作者还给出了Openpose和Canny的区别:
      What’s the difference between using Canny edge detection and Openpose? The Canny edge detector extracts the edges of the subject and background alike. It tends to translate the scene more faithfully. You can see the dancing man became a woman, but the outline and hairstyle are preserved.
      Canny更加的忠实还原,或者说抽象程度低一些,而Openpose更加的触及图像的本质,更加的抽象。当然这个是有代价的,就是它更加的专注于人物的主要部分,而不是通用吧?
      OpenPose only detects human key points such as positions of the head, arms, etc. The image generation is more liberal but follows the original pose.
      这里作者的敏锐的观察力给你作更加细致的分析两者的结果
      The above example generated a woman jumping up with the left foot pointing sideways, different from the original image and the one in the Canny Edge example. The reason is that OpenPose’s keypoint detection does not specify the orientations of the feet.
    9. 安装步骤
      1. Navigate to the Extensions page.
      2. Select the Install from URL tab.
      3. Put the following URL in the URL for extension’s repository field.
      4. https://github.com/Mikubill/sd-webui-controlnet
      5. Click the Install button.
      6. Wait for the confirmation message saying the extension is installed.
      7. Restart AUTOMATIC1111.
      8. Visit the ControlNet models page.
      9. Download all model files (filename ending with .pth).
      10. (If you don’t want to download all of them, you can download the openpose and canny models for now, which are most commonly used.)

      11. Put the model file(s) in the ControlNet extension’s models directory.
      12. stable-diffusion-webui\extensions\sd-webui-controlnet\models
      13. Restart AUTOMATIC1111 webui.
      这个我好像没有看到,可能要等很久吧?
      If the extension is successfully installed, you will see a new collapsible section in the txt2img tab called ControlNet. It should be right above the Script drop-down menu.
  3. 关于这个T2I adaptor我不确定我是否需要。再说吧。
  4. 这里是使用的法门,也是最有用的部分,先下载这个指示图 然后运行过程中发现这个动作一直不前进
    Downloading: "https://huggingface.co/lllyasviel/Annotators/resolve/main/body_pose_model.pth" to /home/nick/workspace/stable-diffusion-webui/extensions/sd-webui-controlnet/annotator/downloads/openpose/body_pose_model.pth
    这里的解决方案还没有证实。也许是证书的问题,也许。。。吃饭了。
  5. 遇到一个打开huggingface.co的错误,说tls的certificated之类的。这个是完全和AI无关的问题。这个应该是最好的答案
    
    ex +'/BEGIN CERTIFICATE/,/END CERTIFICATE/p' <(echo | openssl s_client -showcerts -connect huggingface.co:443) -scq >  huggingface.crt
    
    实际上,有很多更好的答案说到SNI和非SNI的处理,但是对于我来说,我甚至都懒得考虑certificate chain要取多少个的问题。总之,得到对方的证书是要使用的:
    
    sudo cp huggingface.crt /usr/local/share/ca-certificates/
    sudo update-ca-certificates
    
    然后,遇到了下载controlNet的组件的问题,比如
    https://huggingface.co/lllyasviel/Annotators/resolve/main/body_pose_model.pth
    这个位置不对了,需要手动到
    https://huggingface.co/lllyasviel/ControlNet-v1-1/tree/main
    去下载那些body_pose_model.pth, hand_pose_model.pthfacenet.pth,把它们拷贝到
    
    extensions/sd-webui-controlnet/annotator/downloads/openpos
    下去。 但是这一切做完我发现Openpose的人物畸形的很多,我的negative prompt也许不够多吧?我找到这些,结果还是不行,即便换成Canny的模型也是一样,而且,我也尝试换其他的基础模型,总之,效果让人很失望。
  6. 有一种可能是我选取的模型不对,比如这个是作者的公式
    PreprocessorModel
    depth_xxxxcontrol_xxxx_depth
    lineart_xxxxcontrol_xxxx_lineart
    openpose_xxxxcontrol_xxxx_openpose

二月一日 等待变化等待机会

  1. 这篇教程的关于openpose的描述是准确的。
  2. 这个dw_pose的论文我先保存一个拷贝。论文的好处在于它有很多引用是非常经典的学习途径,当然这个是对于专业研究者来说,对于门外汉来说知道标题甚至概述就可以拿出去唬人了。
  3. 其实选择一个好的模型是至关重要的,我看到模型也是互相引用或者说融合的吧,也有剔除等等。
    1. 这个Protogen提到了很多其他模型,我决定一个个来尝试一下,作者所说的keywords难道是各个融合的模型吗?比如(modelshoot style)?
    2. 比如这个看起来是模特的modelshoot
    3. 然后这个 photoreal也下载一下。
    4. openjourney
    5. robo-diffusion
    6. RPG模型出乎我的意料,它包含了好几个我都已经脸熟的好几个模型看来它不是模型提供者,只不过是概念提供者:Recaptioning, Planning, and Generating with Multimodal LLMs
    7. 这个sci-fi科幻还是很让人期待的。 这个是官方的咒语
      • Sci-Fi
      • caspian Sci-Fi
      • Star Citizen
      • Star Atlas
      • Spaceship
      • Render
    8. 这个SynthwavePunk自己的介绍就引出了另外两个它的来源模型:synthwave和punk,这里是原始的模型
    9. 这个就是Synthwave
    10. 这个是comic-diffusion 它说的六个艺术家是关键字吗?我对于训练还是一无所知无法理解。
      • charliebo artstyle
      • holliemengert artstyle
      • marioalberti artstyle
      • pepelarraz artstyle
      • andreasrocha artstyle
      • jamesdaly artstyle
    11. 这个是moistMix V2,还有V1的版本
    12. 我现在回过头来看,很多模型是在最基本的模型上变化而来的,我是否应该从头来看看这些鼻祖模型呢? 这里对于模型的介绍我还是要反复来理解:
      Custom checkpoint models are made with (1) additional training and (2) Dreambooth. They both start with a base model like Stable Diffusion v1.5 or XL.
      • Additional training is achieved by training a base model with an additional dataset you are interested in. For example, you can train the Stable Diffusion v1.5 with an additional dataset of vintage cars to bias the aesthetic of cars towards the vintage sub-genre.
      • Dreambooth, developed by Google, is a technique to inject custom subjects into text-to-image models. It works with as few as 3-5 custom images. You can take a few pictures of yourself and use Dreambooth to put yourself into the model. A model trained with Dreambooth requires a special keyword to condition the model.
      • The checkpoint model is not the only model type. We also have textual inversion (also called embedding), LoRA, LyCORIS, and hypernetwork.
    13. 这个是runwayml的stable-diffusion-v1-5,也许这个是最早的?
    14. 这个是stabilityAI公司的stable-diffusion-2-1
    15. 很多模型似乎不是官方发布的,比如这个看上去似乎是OpenDalle,然后我就找到了这个看上去是官方的。结果就发现模型都存放在这里我还是天真了,既然模型这么重要,当然不大可能都是免费的,这些官方的模型居然是要收费的。 不过这个模型的质量真的不错,这个图我很喜欢,用的是这个prompt: photo of young woman, Star Citizen, standing in front of a spaceship, staring forward, (Star Wars), face camera,(sci-fi style)
    16. 这个是微软的phi-2模型下载来试一试吧。
    17. 我发现在huggingface.co上找模型仅仅依靠关键字并不容易,至少不准确,谁都可以作模型。
    18. 我现在另一个苦恼就是那些咒语,我不知道每个模型所特有的关键字,否则什么模型都是差不多的。
  4. 这个是safetensors的格式。这个我还是看不太懂。这个有什么看不懂的呢?读出前8个byte就是头部的大小。
    
    $>od -N 8 -t d8 3dAnimationDiffusion_v10.safetensors
    0000000               154656
    0000010
    
    所以,头文件的大小是154656,我们可以打印到文件
    dd if=3dAnimationDiffusion_v10.safetensors of=/tmp/3dAnimationDiffusion_v10.txt bs=1 skip=8 count=154656
    文件里究竟是什么结构呢?头文件都是json的结构块。
    
    ...
    "model.diffusion_model.output_blocks.7.1.norm.weight":{"dtype":"F16","shape":[640],"data_offsets":[2049025648,2049026928]},"model.diffusion_model.output_blocks.7.1.proj_in.bias":{"dtype":"F16","shape":[640],"data_offsets":[2049026928,2049028208]},"model.diffusion_model.output_blocks.7.1.proj_in.weight":{"dtype":"F16","shape":[640,640,1,1],
    ...
    
    简言之: "tensor_name":{"dtype":"data type name", "shape":[num1,num2,...], "data_offsets":[begin,end]}
  5. 这里是一个所谓的negative prompt的东西,但是我还没有理解,难道图形也可以作为negative prompt?
    Many AI image generators, including Stable Diffusion, can use an image as a prompt to generate a similar image. On the other hand, we use text prompts to describe what we want and negative prompts to describe what we don’t want. How about a negative image prompt?
    还真的是这个作法!
  6. 我看到了ComfyUI,难道我应该尝试一下?它和webui有什么不同呢? 其实安装的开销不大,因为我已经有了好的环境不需要再次安装了。
    
    source ../stable-diffusion-webui/venv/bin/activate
    python main.py
    
    至于模型,我在models/checkpoints下建立软链接。
    
    ln -s ~/workspace/stable-diffusion-webui/models/Stable-diffusion/OpenDalleV1.1.safetensors .
    
    c 说不定我以后要在我的NAS上存储这些巨型模型吧?ComfyUI的确是非常绚丽,很棒!它给你看到整个流水线的流程!
  7. 昨天买的黑群晖到货了,看来我是小看了这些国内的年轻人,非常的有技术含量,因为那个引导u盘为什么要重启一次呢?从它的输出说是生成启动引导文件,给人一种动态产生的感觉。这个我的猜想是第一次启动得到真实的硬件信息或者驱动,第二次要适配群晖的硬件要求吧?这里的一些资料可以慢慢看吧?

二月二日 等待变化等待机会

  1. 这里总结webui和ConfyUI的对比。 首先,再明确一下模型的位置:
    model typemodel path
    Checkpointstable-diffusion-webui/models/Stable-diffusion
    VAEstable-diffusion-webui/models/VAE
    LoRAstable-diffusion-webui/models/Lora
    LyCORISstable-diffusion-webui/models/LyCORIS
    Embeddingsstable-diffusion-webui/embeddings
    Hypernetworksstable-diffusion-webui/hypernetworks
    Controlnetstable-diffusion-webui/ControlNet
    这里作者原来是想告诉我们一个webui和ComfyUI共享所有模型的方法: 编辑ComfyUI的extra_model_paths.yaml文件让它指向我们webUI的模型路径!这样子我连软链接都不用创建了!我一定要试一下!!!
  2. 如今还有人会被抄袭而苦恼吗?如果我看到了一幅画,我想模仿又不露痕迹,怎么办呢?很简单的,只要我使用img2img功能。

    原图

    模仿图

  3. 我有些看不懂,这个问题是需要img2txt,但是这个CLIP是否就做到了呢?我后来发现这个UI改变了很多,现在变成一个小小的button,我找了好久才找到。第一次运行CLIP它要下载很大的模型,所以,要耐心一些。
  4. 我运行CLIP但是初始化出了很多错误,我决定安装它作为extension来试一下。然后我遇到cdn-lfs.huggingface.co的certificate不对的问题,我怀疑这个和之前的问题类似。有一个时段我在想我是不是应该把对方的certificate chain都加入到我本机的信任的证书里。我发现有人和我有相似的问题。这是一个复杂的问题,复杂的问题没有简单的答案! 因为问题复杂,我连答案都看不大懂。不过我的领悟是:我的问题和他的问题不太一样,他问的是为什么要certficate chain,而我要的是如果我信任了最末端的我还需要信任它的上级吗?或者说我因为某种原因降低了我的警惕,我需要这么大费周张的把所有的证书都下载一遍吗?其实这个问题的复杂就在于我实际上还是不理解为什么证书是有效的。我的电脑里难道没有这个www.digicert.com的根证书吗?似乎还真的没有
    
    nick@nick-sager:~/Downloads$ awk -v cmd='openssl x509 -noout -subject' '
        /BEGIN/{close(cmd)};{print | cmd}' < /etc/ssl/certs/ca-certificates.crt | grep DigiCert
    subject=C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Assured ID Root CA
    subject=C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Assured ID Root G2
    subject=C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Assured ID Root G3
    subject=C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
    subject=C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root G2
    subject=C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root G3
    subject=C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert High Assurance EV Root CA
    subject=C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Trusted Root G4
    subject=C = US, O = "DigiCert, Inc.", CN = DigiCert TLS ECC P384 Root G5
    subject=C = US, O = "DigiCert, Inc.", CN = DigiCert TLS RSA4096 Root G5
    
    撇开中间证书不提,cdn-lfs.huggingface.co的末端证书的确有些不是那么的对头:
    
    nick@nick-sager:~/Downloads$ openssl x509 -noout -subject -in cdn-lfs.huggingface.crt 
    subject=C = US, ST = California, L = Menlo Park, O = "Meta Platforms, Inc.", CN = *.facebook.com
    
    为了验证我的想法,我们先拿微软的bing来作一个对比:
    
    nick@nick-sager:~/Downloads$ ex +'/BEGIN CERTIFICATE/,/END CERTIFICATE/p' <(echo | openssl s_client -showcerts -connect www.bing.com:443) -scq | openssl x509 -noout -subject
    depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root G2
    verify return:1
    depth=1 C = US, O = Microsoft Corporation, CN = Microsoft Azure TLS Issuing CA 02
    verify return:1
    depth=0 C = US, ST = WA, L = Redmond, O = Microsoft Corporation, CN = www.bing.com
    verify return:1
    DONE
    subject=C = US, ST = WA, L = Redmond, O = Microsoft Corporation, CN = www.bing.com
    
    以下都是我在openvpn服务器端作的测试,我在我本地无法得到访问,这个似乎也是一直困扰我的DNS或者是其他什么问题,我始终都在探索中。。。也不是完全不能只是要等的非常非常久 也就是说CN就是你的域名,这样子用户才能相信你。至于说多域名的访问或者说支持SNI,那个就复杂了。再举一个例子
    
    openvpnas@ip-172-31-35-59:~$ ex +'/BEGIN CERTIFICATE/,/END CERTIFICATE/p' <(echo | openssl s_client -showcerts -connect www.google.com:443) -scq | openssl x509 -noout -subject
    depth=2 C = US, O = Google Trust Services LLC, CN = GTS Root R1
    verify return:1
    depth=1 C = US, O = Google Trust Services LLC, CN = GTS CA 1C3
    verify return:1
    depth=0 CN = www.google.com
    verify return:1
    DONE
    subject=CN = www.google.com
    
    看看huggingface.co
    
    openvpnas@ip-172-31-35-59:~$ ex +'/BEGIN CERTIFICATE/,/END CERTIFICATE/p' <(echo | openssl s_client -showcerts -connect huggingface.co:443) -scq | openssl x509 -noout -subject
    depth=2 C = US, O = Amazon, CN = Amazon Root CA 1
    verify return:1
    depth=1 C = US, O = Amazon, CN = Amazon RSA 2048 M01
    verify return:1
    depth=0 CN = huggingface.co
    verify return:1
    DONE
    subject=CN = huggingface.co
    
    如果是cdn-lfs.huggingface.co似乎也是正确的
    
    openvpnas@ip-172-31-35-59:~$ ex +'/BEGIN CERTIFICATE/,/END CERTIFICATE/p' <(echo | openssl s_client -showcerts -connect cdn-lfs.huggingface.co:443) -scq | openssl x509 -noout -subject
    depth=2 C = US, O = Amazon, CN = Amazon Root CA 1
    verify return:1
    depth=1 C = US, O = Amazon, CN = Amazon RSA 2048 M01
    verify return:1
    depth=0 CN = cdn-lfs.huggingface.co
    verify return:1
    DONE
    subject=CN = cdn-lfs.huggingface.co
    
    看起来在openvpn的服务器端是没有问题的。那么证书是没有问题的吧?难道仅仅是连接非常的缓慢导致的问题?
  5. 紧接着上面的问题,就是我要怎么确定问题是不是DNS造成的呢? 我首先比较了我本地和VPN server上的DNS的表现: 为什么会造成这个区别呢?是地域不同所以自然的就不同吗? 这里的回答相当的全面。

    This is because after connecting to a VPN with vpnc, it puts a line in /etc/resolv.conf so it looks like:

    # Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
    #     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
    nameserver 1.2.3.4
    nameserver 127.0.0.1
    search MyDomain
    
    我在openvpn上看到类似的:
    
    nameserver 127.0.0.53
    options edns0 trust-ad
    search us-west-1.compute.internal
    
    所以VPNC修改了DNS的设置。 这里DNS-over-TLS讲到的是另一个高度的问题,我还是看不明白。
    If true all connections to the server will be encrypted. Note that this mode requires a DNS server that supports DNS-over-TLS and has a valid certificate. If the hostname was specified in DNS= by using the format address#server_name it is used to validate its certificate and also to enable Server Name Indication (SNI) when opening a TLS connection. Otherwise the certificate is checked against the server's IP. If the DNS server does not support DNS-over-TLS all DNS requests will fail. When set to opportunistic DNS request are attempted to send encrypted with DNS-over-TLS. If the DNS server does not support TLS, DNS-over-TLS is disabled. Note that this mode makes DNS-over-TLS vulnerable to "downgrade" attacks, where an attacker might be able to trigger a downgrade to non-encrypted mode by synthesizing a response that suggests DNS-over-TLS was not supported. If set to false, DNS lookups are send over UDP. If set to default, uses the system default.
    这个systemd-resolved似乎是我要找的。我太累了。记录一下,随后再找。

二月三日 等待变化等待机会

  1. 很多时候最困难的事情就是你不知道它是什么问题。就是说解决问题的最主要困难是理解问题是什么!首先我就是不理解我的问题究竟是什么,是DNS的问题没错,但是究竟是DNS的服务有问题还是多个设备的不同的DNS服务器的问题,还是说我必须什么访问都要通过openvpn的DNS服务?这个似乎不合理,因为国内网很多有优化,我不可能穿越到外网再回来。但是你怎么区分什么网址需要什么DNS服务?我打算先从最稳妥的做起,就是安装ubuntu官方的openvpn的套件:openvpn-systemd-resolved 这里也始终是我不理解的,究竟DNS的服务是通过哪一个?systemd-resolved还是resolvectl,这个文件/etc/resolv.conf还是起作用的?那么127.0.0.53是做什么用的?而且DNS的解析哪怕你设置对了,在实际运行过程中哪一方的返回快最终决定了实际使用的结果,甚至于有时候你设置了正确的可是因为缓存的缘故不能立刻看到正确的结果导致你对于正确的设置产生怀疑?种种问题的最根本问题还是我不理解问题是什么。连最基本的概念都没有。
    这个是dig的结果
    
    nick@nick-sager:~/workspace/DS918$ dig www.google.com
    
    ; <<>> DiG 9.18.18-0ubuntu0.22.04.1-Ubuntu <<>> www.google.com
    ;; global options: +cmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 55053
    ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 4, ADDITIONAL: 9
    
    ;; OPT PSEUDOSECTION:
    ; EDNS: version: 0, flags:; udp: 65494
    ;; QUESTION SECTION:
    ;www.google.com.			IN	A
    
    ;; ANSWER SECTION:
    www.google.com.		227	IN	A	74.86.3.208
    
    ;; AUTHORITY SECTION:
    google.com.		227	IN	NS	ns3.google.com.
    google.com.		227	IN	NS	ns2.google.com.
    google.com.		227	IN	NS	ns1.google.com.
    google.com.		227	IN	NS	ns4.google.com.
    
    ;; ADDITIONAL SECTION:
    ns2.google.com.		227	IN	AAAA	2001:4860:4802:34::a
    ns1.google.com.		227	IN	A	216.239.32.10
    ns1.google.com.		227	IN	AAAA	2001:4860:4802:32::a
    ns2.google.com.		227	IN	A	216.239.34.10
    ns4.google.com.		227	IN	AAAA	2001:4860:4802:38::a
    ns4.google.com.		227	IN	A	216.239.38.10
    ns3.google.com.		227	IN	A	216.239.36.10
    ns3.google.com.		227	IN	AAAA	2001:4860:4802:36::a
    
    ;; Query time: 0 msec
    ;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
    ;; WHEN: Sat Feb 03 05:29:10 +08 2024
    ;; MSG SIZE  rcvd: 307
    
    那么从头学习基本概念就是必由之路!最基本的DNS的常识我始终是一知半解。
    Record TypeRecord DefinitionRecord Function
    A record The A record is the most important DNS record type. The "A" in A record stands for "address." An A record shows the IP address for a specific hostname or domain. The A record only supports IPV4 addresses. The main use of A record is for IP address lookup. Using an A record, a web browser is able to load a website using the domain name. As a result, we can access websites on the internet without knowing their IP addresses. Another use of A record is in the domain name system-based blackhole list (DNSBL). Here, the A record is used to block mail from known spam sources.
    AAAA record AAAA record, just like A record, point to the IP address for a domain. However, this DNS record type is different in the sense that it points to IPV6 addresses. IPV6 is an upgrade over IPV4 as it offers more IP addresses. As a result, IPV6 solves the issue of running out of unique IP addresses. Usage of the AAAA record for DNS resolution has great potential because it uses IPV6, which is an improvement over IPV4. Also, as the internet keeps growing and we're running out of IPV4 addresses, the potential for AAAA records is high. AAAA records are used to resolve a domain name to the newer IPV6 protocol address.
    CNAME record CNAME—or, in full, "canonical name"—is a DNS record that points a domain name (an alias) to another domain. In a CNAME record, the alias doesn't point to an IP address. And the domain name that the alias points to is the canonical name. For example, the subdomain ng.example.com can point to example.com using CNAME. A practical example for the use of CNAME records is running multiple subdomains for different purposes on the same server. For example, we can use ftp.example.com for file transfer protocol (FTP) and serve webpages via www.example.com. We can then use a CNAME record to point both subdomains to example.com. The main domain example.com then points to the server's IP address using an A record. It's also possible to point a CNAME to another CNAME. However, doing so is inefficient and can lead to slow load speed and poor user experience.
    NS record A nameserver (NS) record specifies the authoritative DNS server for a domain. In other words, the NS record helps point to where internet applications like a web browser can find the IP address for a domain name. Usually, multiple nameservers are specified for a domain. For example, these could look like ns1.examplehostingprovider.com and ns2.examplehostingprovider.com. If you've purchased a web hosting service or set up a simple website, you probably received an email with nameserver details. Those nameservers, in simple terms, connect your domain name to the actual server your site is hosted on. The nameserver contains other DNS records for the domain like an A record and MX record.
    MX record A mail exchange (MX) record, is a DNS record type that shows where emails for a domain should be routed to. In other words, an MX record makes it possible to direct emails to a mail server. You can have multiple MX records for a single domain name. And what this means is that you can have backup email servers. With an MX record, it's possible to hand off emails to a dedicated email server. For example, you can decide to leave all the trouble of setting up webmail on a server you own to a specialized email provider. This comes with many benefits, including custom email clients for reading and sending emails, and improved security and spam filters. Also, you can use a service like Site24x7 to monitor and verify issues with the mail server your MX records point to.
    SOA record SOA stands for "start of authority." It's an important DNS record type that stores admin information about a domain. This information includes the email address of the admin and when the domain was last updated.
    TXT record TXT stands for "text," and this record type lets the owner of a domain store text values in the DNS. Several services use this record to verify ownership of a domain.
    PTR record A pointer (PTR) record provides a domain name for reverse lookup. It's the opposite of an A record as it provides the domain name linked to an IP address instead of the IP address for a domain.
    SRV record SRV stands for service, obviously. Using this DNS record type, it's possible to store the IP address and port for specific services.
    CERT record CERT stands for certificate, obviously. This record type stores public keys certificates.
    DCHID DHCP configuration record This DNS record type stores information related to dynamic host configuration protocol (DHCP).
    DNAME The full meaning of DNAME is "delegation name." This record type works very similarly to CNAME; however, it points all the subdomains for the alias to the canonical domain name. That is, pointing the DNAME for secondsite.com to example.com will also apply to staff.secondsite.com and any other subdomain.
  2. 即便你对于基本的DNS的结构有了初步了解,那么系统如何使用它又是一个大大的领域。单单这个systemd-resolved服务就是多么复杂的一个体系。而且是否所有的应用都是使用它呢?它和NetworkManager的关系是什么呢?应该它是服务的提供者吧。它又可以透过什么DBUS之类的接口,这个又是一个我长久以来不理解的领域。D-BUS看了无数遍依旧不明白它是什么。
  3. 我发现了一个新途径来学习,就是这个官方的openvpn-systemd-resolved包里的说明文档有很多非常有针对性的部分!首先,文档说明了它的目的,似乎就是我要的结果:
    This is a helper script designed to integrate OpenVPN with the `systemd-resolved` service via DBus instead of trying to override `/etc/resolv.conf`, or manipulate `systemd-networkd` configuration files.
    它的工作原理揭示了它必须要配合openvpn服务起来的时候,我作为客户端是否也应该这样子呢?
    Since systemd-229, the `systemd-resolved` service has an API available via DBus which allows directly setting the DNS configuration for a link. This script makes use of `busctl` from systemd to send DBus messages to `systemd-resolved` to update the DNS for the link created by OpenVPN.
    安装部分ubuntu都不需要操心,使用前提也说明了:OpenVPN 2.1 or greater,iproute2, and have at least version 229 of systemd。而且我已经明确知道系统是运行systemd-resolved.service服务的。然后文档提到了NSS,这个又是一个全新的领域,难道Name Service Switch又会横插一杠子?怎么能够集中统一呢?我的初步理解是NSS定义了一个解析的顺序或者说优先级。总之我看不懂,先不要管了。接下来是关于stub的:
    The `systemd-resolved` service (since systemd-231) also listens on `127.0.0.53` via the `lo` interface, providing a stub resolver which any client can call to request DNS, whether or not it uses the system libraries to resolve DNS, and you no longer have to worry about trying to manage your `/etc/resolv.conf` file.
    然后解释的是结果吗?
    This set up can be installed by linking to `stub-resolv.conf`
    
    ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
    
    我发现系统已经是这样子了。我看的头疼死了。歇一歇吧。 这个是更容易阅读的版本。

二月四日 等待变化等待机会

  1. 我依旧不得要领。准本回过头来看看是不是我的openvpn Client端有什么遗漏。
  2. 我尝试使用openvpn官方的版本而不是ubuntu自带的版本。但是下载代码居然有问题,就是说我安装了gpg key,但是访问https的package repo一直不行。
  3. 然后我试图直接从源码编译,这个是源码的repo。结果使用https的git又被openssl reset connection,我不明白这个是不是运营商根据法规禁止还是我自己的问题,总之很多时候是交织在一起。而糟糕的是单单下载这个源码是不够的因为它依赖很多子项目,唯一简单的做法是在git submodule update,所以,我只能去注册一个用户把我的ssh-key放在网站里走ssh clone的办法:
    
    git clone --recursive git@codeberg.org:OpenVPN/openvpn3-linux.git
    
    编译倒是小问题。然后使用起来遇到大问题,因为完全不是我想象的,它的功能似乎是锦上添花的可有可无。我决定放弃。
  4. 我无意中发现ping www.google.com在ipv4下好像还是正确的。而且我再次去验证我的DNS理论发现也许根本没有问题,比如我比较两个网卡得到的DNS结果似乎是一致的。比如我的tun0的ip是172.27.232.49
    
    dig @172.27.232.49 -q www.google.com
    
    这个结果和我本地的网卡是一致的。 然后我决定禁止我的ipV6
    
    sudo sysctl -w net.ipv6.conf.all.disable_ipv6=1
    sudo sysctl -w net.ipv6.conf.default.disable_ipv6=1
    sudo sysctl -w net.ipv6.conf.lo.disable_ipv6=1
    
    然后似乎就正常了。
  5. 终于可以暂时摆脱网络的困扰,可以重回正轨。现在我使用两个不同的模式从输入图像来得到text prompt,似乎DeepBooru得到的这个范冰冰好一些:
    
    1girl, 3d, bare shoulders, blurry, blurry background, blurry foreground, bokeh, cosplay photo, depth of field, hand on own face, head rest, lips, lipstick, long hair, looking at viewer, makeup, photo \(medium\), photo background, photorealistic, realistic, red lips, smile, solo, upper body
    
    依赖这个prompt,使用dreamshaper的模型,我得到的相当准确的图像,至少穿着打扮姿态是狠准的: CLIP得到的是更加的简单:
    
    a woman sitting at a table with a laptop computer in her hand and a brick wall behind her, with a yellow light behind her, phuoc quan, Du Qiong, a character portrait, private press
    
    当然反向再从txt2img是差得更远了。这种interrogate应该也是一种近似吧?
  6. 现在回到当初的这个教程。作者说这个是ComfyUI的custom-node。要学习怎么安装。先明确一下定义是什么
    The IPAdapter are very powerful models for image-to-image conditioning. Given a reference image you can do variations augmented by text prompt, controlnets and masks. Think of it as a 1-image lora.
    安装 这里有两个encoder需要下载
    IPAdapter also needs the image encoders. You need the CLIP-ViT-H-14-laion2B-s32B-b79K and CLIP-ViT-bigG-14-laion2B-39B-b160k image encoders, you may already have them. If you don't, download them but be careful because the file name is the same! Rename them to something easy to remember and place them in the ComfyUI/models/clip_vision/ directory.
    这个表看样子很重要,因为牵涉到不同的模型和image-encoder的组合
    SD v. IPadapter Img encoder Notes
    v1.5 ip-adapter_sd15 ViT-H Basic model, average strength
    v1.5 ip-adapter_sd15_light ViT-H Light model, very light impact
    v1.5 ip-adapter-plus_sd15 ViT-H Plus model, very strong
    v1.5 ip-adapter-plus-face_sd15 ViT-H Face model, use only for faces
    v1.5 ip-adapter-full-face_sd15 ViT-H Strongher face model, not necessarily better
    v1.5 ip-adapter_sd15_vit-G ViT-bigG Base model trained with a bigG encoder
    SDXL ip-adapter_sdxl ViT-bigG Base SDXL model, mostly deprecated
    SDXL ip-adapter_sdxl_vit-h ViT-H New base SDXL model
    SDXL ip-adapter-plus_sdxl_vit-h ViT-H SDXL plus model, stronger
    SDXL ip-adapter-plus-face_sdxl_vit-h ViT-H SDXL face model
  7. 至少我突然明白了一个尽人皆知的东西,就是ComfyUI是可以非常灵活或者说可靠的定义的,因为它是用一个json文件来描述它的UI,也就是说很通用。所以,当作者说参考这些范例我才能明白ComfyUI有多么的强大好用。当然作者的范例里有硬代码了输入文件名是一个遗漏。
  8. 我对于negative image prompt不太理解了,因为我使用图像本身作为negative image prompt,结果会怎么样子呢?我看不懂。还是先从原理学习一下吧。
    1. A brief history of negative prompts

      Initially, diffusion-based AI image generators could generate random, high-quality images. But there was no way to control what you generate. It just generates images that resembles the training data.
    2. 然后这里就是很重要的部分:
      Then, classifier-free guidance came into play. It hijacks the attention layers to inject the text embeddings to the sampling steps. The model is then trained with image and caption pairs. When generating an image, the model steers the images toward the prompt and away from the random images.
    3. 这里一个个来学习吧:原来CFG就是Classifier-Free Guidance的缩写。首先,什么是Classifier-Guidance:
      Classifier guidance is a way to incorporate image labels in diffusion models. You can use a label to guide the diffusion process.
      这样子举例就容易懂了就是训练时候加标签来分类。这里又引出了CFS这个常见的参数
    4. The classifier guidance scale is a parameter for controlling how closely should the diffusion process follow the label.
      这里我们记录一下引用的最原始的论文。这是拷贝
    5. With high classifier guidance, the images produced by the diffusion model would be biased toward the extreme or unambiguous examples. If you ask the model for a cat, it will return an image that is unambiguously a cat and nothing else.
      也就是说CFS高的话,AI会选择最无争议的图。
    6. The classifier guidance scale controls how closely the guidance is followed. In the figure above, the sampling on the right has a higher classifier guidance scale than the one in the middle. In practice, this scale value is simply the multiplier to the drift term toward the data with that label.
      这里的drift term toward the data with that labe指的是什么参数呢?
    7. 那么什么是Classifier-free guidance呢?首先,它的产生的原因就是它是什么。
      Although classifier guidance achieved record-breaking performance, it needs an extra model to provide that guidance. This has presented some difficulties in training.
      当然不希望反反复复去训练,能不能在模型的基础上改进一下就行了呢?
    8. Classifier-free guidance, in its authors’ terms, is a way to achieve “classifier guidance without a classifier”. Instead of using class labels and a separate model for guidance, they proposed to use image captions and train a conditional diffusion model, exactly like the one we discussed in text-to-image.
      我觉得这段话就是核心要深刻领会。首先是不用模型来再训练改变模型,靠的是什么?condition吗?还有uncondition。原论文概要里这句话也非常的重要:
      Classifier guidance combines the score estimate of a diffusion model with the gradient of an image classifier and thereby requires training an image classifier separate from the diffusion model. It also raises the question of whether guidance can be performed without a classifier.
      这里都是关键点。难怪作者说classifier guidance without a classifier
    9. 我觉得要先回顾一下什么是text-conditioning,才能从本质上理解怎么才能做到classifier guidance without a classifier
      Tokenizer first converts each word in the prompt to a number called a token. Each token is then converted to a 768-value vector called embedding. The embeddings are then processed by the text transformer and are ready to be consumed by the noise predictor.
    10. 从一个概念引出一群的概念,什么是CLIP呢?
      The CLIP model was proposed in Learning Transferable Visual Models From Natural Language Supervision .
      从标题猜测是从基本模型直接转用到图形吗?梗概很难懂。看实际的说明吧。
      CLIP is a multi-modal vision and language model. It can be used for image-text similarity and for zero-shot image classification. CLIP uses a ViT like transformer to get visual features and a causal language model to get the text features. Both the text and visual features are then projected to a latent space with identical dimension. The dot product between the projected image and text features is then used as a similar score.
      这是需要好好阅读的核心定义。为什么使用dot product呢?两个向量的点乘的数学含义是什么?
      The dot product, also called scalar product, is a measure of how closely two vectors align, in terms of the directions they point.
      ,的确,这个就是计算两个向量的相似度,所以,这个就是使用点乘的意思。
    11. To feed images to the Transformer encoder, each image is split into a sequence of fixed-size non-overlapping patches, which are then linearly embedded. A [CLS] token is added to serve as representation of an entire image.
      所以,这个就是我们怎么计算图像的数字签名或者说特征值吧,一个个grid或者patch的向量。当然还有总的
      CLS stands for classification and its there to represent sentence-level classification.
      这里来理解一下什么是CLS token。
      In order to better understand the role of [CLS] let's recall that BERT model has been trained on 2 main tasks:
      1. Masked language modeling: some random words are masked with [MASK] token, the model learns to predict those words during training. For that task we need the [MASK] token.
      2. Next sentence prediction: given 2 sentences, the model learns to predict if the 2nd sentence is the real sentence, which follows the 1st sentence. For this task, we need another token, output of which will tell us how likely the current sentence is the next sentence of the 1st sentence. And here comes the [CLS]. You can think about the output of [CLS] as a probability.
    12. 补习一下概念
      CLIP, which stands for Contrastive Language-Image Pre-training, is a model for telling you how well a given image and a given text caption fit together. In training, it tries to maximize the “cosine similarity” between correct image-caption vector pairs, and minimize the similarity scores between all incorrect pairs.
    13. 补习英文
      The adjective contrastive means "showing the difference between two things when you compare them" — like a contrastive analysis of American and British English. To contrast two things is to think about how they are different.

二月五日 等待变化等待机会

  1. 可以说每一步都是概念,What Are SOTA DNNs
    State-of-the-art (SOTA) Deep Neural Networks (DNNs) are the best models you can employ for a specific task. A DNN can earn the SOTA label based on its accuracy, speed, or any other relevant metric. However, in many computer vision domains, there exists a trade-off among these metrics. In other words, you might have a DNN that is very fast, but its accuracy falls short. Conversely, there are DNNs with impressive accuracy metrics that lack the necessary latency or throughput across various tasks, such as image classification and object detection. In these domains, a DNN will be deemed SOTA if it delivers an optimal trade-off between the relevant metrics.
    而这句话里有多少缩写单词我看不懂:
    The metrics we usually use to compare and evaluate DNNs are accuracy, precision, recall, F1-score, IoU, and mAP.
  2. 这里又是两个新的概念CNN和ViT:
    Convolutional Neural Networks (CNNs) and Vision Transformers (ViTs) are architectures commonly used in computer vision, each using a unique method of processing visual data.
    • CNNs have been the cornerstone for image processing tasks. They employ convolutional layers to systematically scan images, initially detecting basic features like edges and progressively identifying more intricate patterns deeper in the network. Due to their structured approach, CNNs have excelled in tasks such as image classification and object detection.
    • ViTs introduce a novel approach to image analysis. Originating from transformer architectures initially developed for natural language processing, ViTs segment images into fixed-size patches and process them as sequences, not grids. Their inherent attention mechanisms enable them to discern relationships between various patches, capturing context and offering an interpretation distinct from CNNs. This innovative perspective by ViTs has enriched the computer vision domain, igniting extensive research into synergies between them and CNNs.
  3. CNN的图像识别分类工作原理其实是人皆公知
    In essence, CNNs methodically sift through an image, detect hierarchical features using convolutions, distill essential information, and employ dense layers to draw conclusions about the image’s content.
    那么ViT呢?
    In a nutshell, ViTs deconstruct an image into numerical representations, infuse it with spatial context, and harness the transformer’s capabilities to evaluate and classify the visual data.
    我对于ViT是如何保持其空间感知能力感到不解,这个具体是什么意思
    ViTs incorporate a positional embedding to each patch embedding, ensuring the model retains spatial awareness of each segment’s origin within the image.
    什么叫做positional embedding?是其中某一个?
  4. 还是要先学习transformer的基本概念。
    A transformer is a deep learning architecture based on the multi-head attention mechanism, proposed in a 2017 paper "Attention Is All You Need".
    Attention这个词反复出现 这个流程似乎是很多文章里描述的,但是我依旧不理解。这篇论文保存一下。顺便说一下,这个人尽皆知的缩写的意思: generative pre-trained transformers (GPT)。论文是看不懂的,但是里面的名词是有印象的。这就是进步。
  5. 很多时候我不确定这个是论文的机制吗?
    Transformers provides APIs and tools to easily download and train state-of-the-art pretrained models. Using pretrained models can reduce your compute costs, carbon footprint, and save you the time and resources required to train a model from scratch.
    或者说我看到的论文是训练的机制,那么这里是使用GPT,机制当然是不同的。
  6. 理论往往并不能解答疑问,反而带来更多的疑问。也许只有实践能够在实践中回答疑问。
  7. 这段话的理解也是一个关键。什么叫做conditioned with negative prompt
    The idea was simple: Instead of steering away from a random image, you steer away from the images described by the negative prompt. Technically, you only need to replace the unconditioned latent image with the one that’s conditioned with the negative prompt.
    这幅图是很容易理解,但是什么叫做unconditional sampling with negative prompt?这里为什么是unconditional
  8. 这里又解释了一遍,我依然没有懂:
    The technique for enabling the negative prompt can be applied to images. We encode the negative image to an embedding and inject it into the sampling process of the “unconditioned” latent.
    因为这里的unconditioned latent我不明所以。不过我实验的结果并不满意,也许是模型使用的问题,也许是参数输入的问题。总之,我决定继续。
  9. 这个关于stable-diffusion的模型介绍还不错。虽然已经是一年多前的旧文,对于我来说还是学习的材料。
    ...this text encoder is a special Transformer language model (technically: the text encoder of a CLIP model). It takes the input text and outputs a list of numbers representing each word/token in the text (a vector per token).
    这个和我看的论文是相符合的。
    • Image information creator

      This component runs for multiple steps to generate image information. This is the steps parameter in Stable Diffusion interfaces and libraries which often defaults to 50 or 100. The image information creator works completely in the image information space (or latent space). The word “diffusion” describes what happens in this component. It is the step by step processing of information that leads to a high-quality image being generated in the end (by the next component, the image decoder).
    • Image Decoder

      The image decoder paints a picture from the information it got from the information creator. It runs only once at the end of the process to produce the final pixel image.
    这里是总的概述

    With this we come to see the three main components (each with its own neural network) that make up Stable Diffusion:

    • ClipText for text encoding.
      Input: text.
      Output: 77 token embeddings vectors, each in 768 dimensions.

    • UNet + Scheduler to gradually process/diffuse information in the information (latent) space.
      Input: text embeddings and a starting multi-dimensional array (structured lists of numbers, also called a tensor) made up of noise.
      Output: A processed information array

    • Autoencoder Decoder that paints the final image using the processed information array.
      Input: The processed information array (dimensions: (4,64,64))
      Output: The resulting image (dimensions: (3, 512, 512) which are (red/green/blue, width, height))

  10. 又要补习英语,这个tensor究竟要怎么理解,中文翻译是张量,可是我读这个定义感觉它就是影射,或者是一个高级函数?
    In mathematics, a tensor is an algebraic object that describes a multilinear relationship between sets of algebraic objects related to a vector space. Tensors may map between different objects such as vectors, scalars, and even other tensors. There are many types of tensors, including scalars and vectors (which are the simplest tensors), dual vectors, multilinear maps between vector spaces, and even some operations such as the dot product. Tensors are defined independent of any basis, although they are often referred to by their components in a basis related to a particular coordinate system; those components form an array, which can be thought of as a high-dimensional matrix.
  11. 这个是灵魂拷问:

    What is Diffusion Anyway?

    Diffusion is the process that takes place inside the pink “image information creator” component. Having the token embeddings that represent the input text, and a random starting image information array (these are also called latents), the process produces an information array that the image decoder uses to paint the final image.

    如果使用了这么长时间我不能回答这个问题,我就是白学了。 可以搞笑的回答,diffusion就像是在炒菜,把一堆输入的文字配合一系列的调味品炒出一锅菜。这个当然是向大妈大爷们解释的方式了。
  12. 好累啊。休息一下啊。

二月七日 等待变化等待机会

  1. 这篇启蒙文章确实非常的棒,不仅翔实,而且图文并茂,并且有大量的引用论文。这里就是一篇我认为挺重要的关于latent diffusion论文。对了论文的标题应该是很多人熟悉的:Departure to Latent Space
  2. 这个latent diffusion项目有一个所谓的model zoo,可以使用它的脚本下载。我现在对于DM和LDM的异同还一窍不通,不妨先下载来看看。放着吧。
  3. 再补习一下英语,到底latent space是什么定义呢? 这个是原文定义:
    A latent space, also known as a latent feature space or embedding space, is an embedding of a set of items within a manifold in which items resembling each other are positioned closer to one another. Position within the latent space can be viewed as being defined by a set of latent variables that emerge from the resemblances from the objects.
    说来惭愧,英文定义我也看的不是很明白。对照一些中文版本来更准确的理解吧:
    潜空间(Latent Space)也被称为潜特征空间嵌入空间,是一组元素在流形内的嵌入,相似的元素在潜空间内的距离较小。潜空间中的位置由一组潜变量定义,这些潜变量产生于元素间的相似性。
    这个概念之所以重要就是因为latent space并不一定和feature space有相同的dimension,通常是低维的,而降维打击在这里形成了所谓的数据压缩。这个形象非常的重要,因为只有理解了这一点才能理解为什么之前浙大的那篇论文他们能够通过平面图脑补三维模型,因为在模型的创建的根本意义就在于数据的压缩和提纯,否则模型如果是简单的客观世界的直接反映那就失去了建立模型的根本意义,没有对客观世界的数据压缩就不算机器学习,学习的过程就是一个降维打击的过程或者说数据压缩的过程。如果没有领悟这个最最浅显的基本道理,就不要再学习机器学习了,因为机器都比你懂学习!

    但是这个说法其实也有一种自相矛盾的悖论的感觉。本身我们看到的二维图像难道其本质是高维的吗?在图像识别的意义(semantical)层面肯定是的。就连人们输入的text prompt看起来是一维的字符串在意义层面也要高维来解释。而latent space的一个做法是把它映射到二维图像,这个当然不是从二维到二维的简单映射,这个是我一时犯糊涂才会这么想。

    从一个空间到另一个空间的映射经过了从低维到高维,又从高维到低维的复杂的转换,这个也许就是transformer吧?总之像极了那句咒语:From light to darkness; From darkness, light!

    模型的另一重意义在于它的可复用性,否则也是没有意义的。也就是论文里说的:训练一次,反复使用。

    A notable advantage of this approach is that we need to train the universal autoencoding stage only once and can therefore reuse it for multiple DM trainings or to explore possibly completely different tasks.
  4. 明白了Markov Chain也就明白了DM为什么是一个概率模型,而这个在我看来就是一系列的条件概率,也许这个conditioning就是conditional probability的condition。
    A Markov process is a stochastic process that satisfies the Markov property[1] (sometimes characterized as "memorylessness"). In simpler terms, it is a process for which predictions can be made regarding future outcomes based solely on its present state and—most importantly—such predictions are just as good as the ones that could be made knowing the process's full history.

    在我看来Markov Chain的特点有一点点类比于Context-Free-Language(CFG),至少从上下文无关的条件概率的角度来看,只不过CFG的概率只能是0或者100。而推而广之,也许世界上都是CFG,只不过有些Context Sensitive的语言的上下文相当的大,而且要打破某种递归循环导致的无限性。总而言之,condiitional和unconditional也许也不过是某种准确性与性能可接受的准确度的妥协的结果,在概率模型下,只要准确度超过一定临界值它的上下文或者条件就可以放宽。

    那么概率模型是否注定不是一个准确的模型呢?人类的罗辑的无模糊性是否天生就和人类自然学习过程的概率模型不兼容?或者说机器学习模仿人类的学习过程反而从一开始就背离了无含糊余地的罗辑推理模型。也许从概率模型进行归纳的过程从而最终上升到罗辑推理模型是一个本质的飞跃,而不是一个量变的简单积累。这个是几十年后才会面对的问题,人类现在不需要操心。
  5. 那么与概率模型相对应的模型注意力机制模型(Attention-Model)。
    Machine learning-based attention is a mechanism which intuitively mimicks cognitive attention. It calculates "soft" weights for each word, more precisely for its embedding, in the context window. These weights can be computed either in parallel (such as in transformers) or sequentially (such as recurrent neural networks). "Soft" weights can change during each runtime, in contrast to "hard" weights, which are (pre-)trained and fine-tuned and remain frozen afterwards.
    是否可以通俗的理解就是赋予不同部分不同的重要性,事实上就是根据权值来取舍,这个是一种很粗暴的压缩方式,直接忽略。简单粗暴导致了质量的不稳定。因为不明白注意力的规律,硬权值往往不可靠便改成了软权值,然而软权值像极了DM这种条件概率模型的方式,只不过怎么产生软权值永远是最核心的部分:怎么实现才是最重要的,因为人人都明白要什么。

    Attention的机制实际上是模仿人类的语言理解过程,在《Yes, (Prime) Minister》里说普通人只能一次理解一个句子,因为长句子导致听众在听了后半截就已经忘了前半段。这个就是现代普通人的注意力机制,尤其是妇女它们的注意力不能保持三秒。从这个角度来看Attention的机制可以看作是一个简单的上下文机制。线性递减。

  6. 反复看到这个概念词autoencoder
    An autoencoder is a type of artificial neural network used to learn efficient codings of unlabeled data (unsupervised learning). An autoencoder learns two functions: an encoding function that transforms the input data, and a decoding function that recreates the input data from the encoded representation. The autoencoder learns an efficient representation (encoding) for a set of data, typically for dimensionality reduction.
    然后数学部分我就看不懂了,只明白这一句话:An autoencoder, by itself, is simply a tuple of two functions.
  7. 很明显的,wiki太过于专业,很难懂因为严谨学术。这里有一个有趣的关于CLIP训练的方式。
    CLIP is trained on a dataset of images and their captions. In actuality, CLIP was trained on images crawled from the web along with their “alt” tags.
    这个是我没有想到的,原来利用了alttag。
    CLIP is a combination of an image encoder and a text encoder. Its training process can be simplified to thinking of taking an image and its caption. We encode them both with the image and text encoders respectively. We then compare the resulting embeddings using cosine similarity.
    这个所谓的cosine similarity应该指的就是计算text vector和image vector的dot product。
  8. 我想尝试一下这个latent diffusion,结果发现我的显卡显存不足。之前还遇到ldm版本不对的问题,我的解决方法似乎不太一样,我是使用python3而不是python命令来解决的:
    
    python3 scripts/knn2img.py  --prompt "a happy bear reading a newspaper, oil on canvas"
    
    但是使用小尺寸
    --W 256 --H 256
    GPU显存不足的问题依旧不能解决,这个帖子有很多建议可以去尝试。

二月八日 等待变化等待机会

  1. 我才突然意识到革命不是瞬间发生的,AI的火种是好多年的积累,那么这个大模型最初是在最容易突破的自然语言处理(NLP)发生的。所以,要读一下这个简介BERT。刚开了个头就被打断了。 这个是训练的两个步骤:半监督学习和监督学习过程。使用wiki作为学习资料看样子是非常有意义的,因为这个可以说是最最完整规范的文字图片材料集散地。视频和图像就不大有类似,也许Youtube?
  2. 我成了论文的收藏家,基本也除了前言看得懂其他都不懂。
    BERT is basically a trained Transformer Encoder stack.
    这个难道是我唯一看得懂的吗?看来我需要先理解它的基础transformer再强调一遍:CLS here stands for Classification.
  3. 这位大师有很多文章,不过依然太专业了我看不懂。

二月九日 等待变化等待机会

  1. 我放弃读论文的前言了,因为即使是梗概和简介部分也是挺不容易的。需要大量的知识储备,最大的作用也许是熟悉一些常见的名词,至少我现在理解什么是SOTA是什么东东了。所以,回过头来看也许这个一步步讲解也许是适合我的水平。我准备今天就集中注意力在这个简介上,至少它引入了一个个概念与步骤。
  2. 开宗明义关于stable-diffusion能做什么和它的模型的简介这部分我这几天算是基本明白了,可以通过了温故而知新,我还是发现很有意义与帮助的
    Stable Diffusion belongs to a class of deep learning models called diffusion models. They are generative models, meaning they are designed to generate new data similar to what they have seen in training. In the case of Stable Diffusion, the data are images.
    这里很有趣的是指出了名字的由来:Why is it called the diffusion model? Because its math looks very much like diffusion in physics.
  3. 魔鬼在细节,每当我庆幸自己学到了什么就发现我几乎还是一无所知,比如什么是forward diffusion?我似乎看到过这个描述的过程,但是没有这么讲解我真的没有理解。
    A forward diffusion process adds noise to a training image, gradually turning it into an uncharacteristic noise image. The forward process will turn any cat or dog image into a noise image. Eventually, you won’t be able to tell whether they are initially a dog or a cat. (This is important)
    为什么要在训练好的模型里添加噪音呢?我模糊记得论文提到了不同类型的噪音,但是这个用意我却没有理解,你把你清晰的印象掺沙子让你的印象模糊起来,这样子才能经受住未来的考验?彷佛令狐冲学习独孤九剑的剑法之后,风轻扬大师问他忘记了多少,最后以至于完全忘记了才能无招胜有招,因为从具体到抽象的过程似乎就是一个逐渐遗忘或者说忽略细节存留根本的过程,也许遗忘不是最好的提取方法,但是往往最本质的特征之所以是最根本的特征就在于它的抗干扰最强,所以,我们掺沙子就以为着我们希望我们的模型能够举一反三抓住模型的根本特征,而不是简单的猫有四条腿,狗有四条腿,所以,狗就是猫的形而上学式的学习。
  4. 如果我们的模型被噪音淹没而无法提取那么我们就是在作无用功,这reverse diffusion才是目的与关键。
    Technically, every diffusion process has two parts: (1) drift and (2) random motion. The reverse diffusion drifts towards either cat OR dog images but nothing in between. That’s why the result can either be a cat or a dog.
    这句话很关键,但是drift and random这两个是什么含义呢?它的效果我是理解了,这个逆向过程一定是一个明确的答案,是或者不是,已经没有概率的问题了,就是你的根本的特征值是被绛帷了,失去了一些额外的细节导致你可以抓住事物最根本的属性,而这个成为判断的最有力的证据,所以,你的答案是斩钉截铁的。
  5. 理解为什么和什么也许是最重要的,可是成功的源头在于怎么做!因为魔鬼依旧在细节,即便Most ones know the path, but only few can actually walk the path.
    To reverse the diffusion, we need to know how much noise is added to an image. The answer is teaching a neural network model to predict the noise added. It is called the noise predictor in Stable Diffusion. It is a U-Net model.
    这里的细节就是加噪音不是随便的,否则连小孩子都会掺沙子,关键是加噪音的时候要训练预测噪音,这一点就很高深了。
    1. Pick a training image, like a photo of a cat.
    2. Generate a random noise image.
    3. Corrupt the training image by adding this noisy image up to a certain number of steps.
    4. Teach the noise predictor to tell us how much noise was added. This is done by tuning its weights and showing it the correct answer.
    这个过程在我看来似乎是说我们人类的记忆遗忘并不是线性或者随机的,遗忘的过程是有模板特征的,如果我们能够学习怎么遗忘那么我们就能学会怎样回忆。如果我们能够学会从零星的记忆碎片重新拼凑出原始的记忆,我们甚至于根本不需要记忆那么多的细节,这个就是压缩数据的高超的做法,对于有规律的数据我们用科学的算法进行冗余数据归类式的无损压缩,但是对于无规律的记忆数据我们模仿记忆模糊的规律来复原最初的记忆从而起到了如梦境般的效果,似幻似真就是太虚幻境,也就是梦境,那么我们能不能把stable diffusion称作梦工厂呢?
  6. 这里我并行的要尝试安装anaconda,这个是具体的安装指南。我模糊记得去年我遇到conda总是有很多冲突,但愿不要把我安装的nvidia的驱动又搞乱了。
    
    If you'd prefer that conda's base environment not be activated on startup,
       run the following command when conda is activated:
    
    conda config --set auto_activate_base false
    
    You can undo this by running `conda init --reverse bash`?
    
    我想起来了,这个就是我讨厌conda的地方,当时它搞乱了系统我不得不卸载。看来我可以不用卸载而不用它。
    
    You have chosen to not have conda modify your shell scripts at all.
    To activate conda's base environment in your current shell session:
    
    eval "$(/home/nick/anaconda3/bin/conda shell.bash hook)" 
    
    To install conda's shell functions for easier access, first activate, then:
    
    conda init
    
    这个是更加稳妥的做法。就是说使用conda先运行conda init,它会改.bashrc,然后重启console,应该可以source .bashrc吧?难说?用完了可以conda init --reverse bash复原.bashrc。手动修改我感觉既麻烦也不好。anaconda的初始化下载进度条作的很好看!
    
    numpy-1.19.2         | 10 KB     | ############################################################# | 100% 
    ca-certificates-2023 | 126 KB    | ############################################################# | 100% 
    intel-openmp-2021.4. | 4.2 MB    | ############################################################# | 100% 
    mkl-service-2.4.0    | 59 KB     | ############################################################# | 100% 
    torchvision-0.8.1    | 17.9 MB   | ############################################################# | 100% 
    libffi-3.3           | 50 KB     | ############################################################# | 100% 
    wheel-0.41.2         | 108 KB    | ############################################################# | 100% 
    libdeflate-1.17      | 64 KB     | ############################################################# | 100% 
    pip-20.3.3           | 1.8 MB    | ############################################################# | 100% 
    libuv-1.44.2         | 864 KB    | ############################################################# | 100% 
    mkl-2021.4.0         | 142.6 MB  | ############################################################# | 100% 
    mkl_random-1.2.2     | 308 KB    | ############################################################# | 100% 
    cudatoolkit-11.0.221 | 622.9 MB  | #####################################################7        |  88% 
    mkl_fft-1.3.1        | 180 KB    | ############################################################# | 100% 
    typing_extensions-4. | 54 KB     | ############################################################# | 100% 
    pytorch-1.7.0        | 663.0 MB  | #############################################1                |  74% 
    python-3.8.5         | 49.3 MB   | ############################################################# | 100% 
    setuptools-68.2.2    | 948 KB    | ############################################################# | 100% 
    ninja-1.10.2         | 8 KB      | ############################################################# | 100% 
    xz-5.4.5             | 646 KB    | ############################################################# | 100% 
    numpy-base-1.19.2    | 10.1 MB   | ############################################################# | 100% 
     ... (more hidden) ...
    
    使用之前要初始化环境:
    
    conda env create -f environment.yaml
    conda activate ldm
    
    的确像我担心的那样子,conda的环境似乎不行,总是抱怨一些库没有安装。我还是不要冒险使用了。

二月十日 等待变化等待机会

  1. 至少我们现在知道stable-diffusion的的训练项目就是得到noise predictor的对于噪音的估计。
    After training, we have a noise predictor capable of estimating the noise added to an image.
    很多的技术核心都是在训练中,否则也不可能有这些年的突破。这里有关于sampler的文章,可以接下去阅读。
  2. 一个大转折是作者打得埋伏,这个实际上不是真的stable-diffusion,因为这个发生在image空间,它很慢需要大量的资源。对于512x512的图片如果是rgb三原色,那么纬度是怎么计算的?就是简单的512x512x3=786432。 这也难怪太大了,而之前提到相应的标签的语言的纬度要和图片一样才能进行点乘吧?所以,语言的纬度肯定不可能有这么大,那么图像的纬度要降低才行吧?所以,这里才引出了我昨天看的latent diffusion。这个是怎么做到的呢?
    Stable Diffusion is a latent diffusion model. Instead of operating in the high-dimensional image space, it first compresses the image into the latent space. The latent space is 48 times smaller so it reaps the benefit of crunching a lot fewer numbers. That’s why it’s a lot faster.
    就是说压缩了48倍,为什么是48?
  3. 这里的核心是另一个大神,Variational AutoEncoder(VAE)。只闻其名,不明其所以然。既然是autoencoder自然就包含了encoder和decoder。 这里的核心自然是latent space,它是一个什么样子的空间?
    So during training, instead of generating a noisy image, it generates a random tensor in latent space (latent noise). Instead of corrupting an image with noise, it corrupts the representation of the image in latent space with the latent noise. The reason for doing that is it is a lot faster since the latent space is smaller.
    核心依旧是latent-tensor,我的英文的理解始终卡在这些基本的概念上,tensor是向量的更高阶的物件吗?否则它怎么能够代替或者说压缩了image space的向量呢?也许它就是图形里的所谓的特征值,就是你把图形的512x512x3这个纬度划分出一个个区块,比如一个区块全是空白自然没有必要罗列那些纬度,这个和压缩是一个原理,只不过实现的方式是不一样吧?
  4. The image resolution is reflected in the size of the latent image tensor. The size of the latent image is 4x64x64 for 512×512 images only. It is 4x96x64 for a 768×512 portrait image. That’s why it takes longer and more VRAM to generate a larger image.
    读到这里我以为这个想法并没有那么难的想到,为什么是48?512/64=8,然后它的平方的3/4就是48,为什么是三通道的三原色改成了四通道?总之,我觉得一般人都能够想到用grid来代替最初的逐个像素,至少如同缩略图一样牺牲一些细节吧?
  5. 或许我很多年前就想到类似的embedding的概念,这个不是天上掉下来的,也不是什么灵光一线的神奇想法,但是具体实现就是最前沿的开拓者才有资格去做。当然这里最基本的问题是如果限制了图像的大小如何要产生大的图呢?这里有所谓的AI-Upscaler,这个也是下一步的阅读。另一个途径是image-to-image function for image upscaling看来大图也是可以拼起来的吧?或者不是拼,是某种放大?作者还提到了第三种途径就是使用大的训练的模型图SDXL模型
  6. 我在犹豫是不是有必要先过一遍SDXL呢?最后决定还是先继续把整个流程走完一遍再说。 因为这里的核心就是latent space,它是什么东西呢?这一句是提纲:Natural images are not random. The high dimensionality of images is artifactual.这里结论很重要,这里的压缩是无损的?
    Natural images can be readily compressed into the much smaller latent space without losing any information. This is called the manifold hypothesis in machine learning.
    第一句定义就让人哑口无言!
    The manifold hypothesis posits that many high-dimensional data sets that occur in the real world actually lie along low-dimensional latent manifolds inside that high-dimensional space.
    latent-manifold这是个什么东西?这个是embedding的定义:
    In mathematics, an embedding (or imbedding) is one instance of some mathematical structure contained within another instance, such as a group that is a subgroup.
    我对于拓扑学最最朴素的认识大概就是这个笑话:
    An often-repeated mathematical joke is that topologists cannot tell the difference between a coffee mug and a donut,[1] since a sufficiently pliable donut could be reshaped to the form of a coffee mug by creating a dimple and progressively enlarging it, while preserving the donut hole in the mug's handle. This illustrates that a coffee mug and a donut (torus) are homeomorphic.
  7. 很多的数学概念都是第一次接触,总是感觉自己的数学基础很差。只好绕过去。
    1. A random latent space matrix is generated.
    2. The noise predictor estimates the noise of the latent matrix.
    3. The estimated noise is then subtracted from the latent matrix.
    4. Steps 2 and 3 are repeated up to specific sampling steps.
    5. The decoder of VAE converts the latent matrix to the final image.
    这个过程堪比化腐朽为神奇,因为古人认为苍蝇蚊子是无中生有的,你能够从一堆噪音里经过提纯剥去噪音得到最终的隐藏的真相,这个简直就是奇迹。也许是从混乱到秩序的一个过程?
  8. VAE仅仅是用来提高眼睛和脸的吗?也许是人对于眼睛和脸的异常敏感我们需要额外的处理?默认的模型都是自带VAE的。但是有些模型说VAE-baked,就是说它需要自己的VAE文件,这一点我已经知道了。
    Stability AI released two variants of fine-tuned VAE decoders, EMA and MSE. (Exponential Moving Average and Mean Square Error are metrics for measuring how good the autoencoders are.)
    原来EMA-pruned是指的这个。
    EMA produces sharper images while MSE’s images are smoother.
    这个也许就够了。下载stabilityAI公司的EMA和MSE也许也是必要的。

    Download link for EMA VAE

    Download link for MSE VAE

    Compressing an image into the latent space does lose information since the original VAE did not recover the fine details. Instead, the VAE decoder is responsible for painting fine details.
    这一点还是很重要的,不要以为存在无损压缩这个事情。而VAE decoder是负责细节的。
  9. 这个是关于conditioning的非常精辟的描述:
    This is where conditioning comes in. The purpose of conditioning is to steer the noise predictor so that the predicted noise will give us what we want after subtracting from the image.
    这里先歇一下吧。

二月十一日 等待变化等待机会

  1. 对于text prompt的工作机制,我还是很意外的,我本来以为整个text prompt是转为一个embedding,但是似乎是每一个词都转为一个768-value的vector,这个768是什么来头?难道是256x256x3代表了256边长的矩阵配合rgb三原色,我总是要它和图形的向量联系起来,否则怎么作点乘呢?
    Each token is then converted to a 768-value vector called embedding.
  2. The text prompt is first tokenized by a CLIP tokenizer. CLIP is a deep learning model developed by Open AI to produce text descriptions of any images. Stable Diffusion v1 uses CLIP’s tokenizer.
    这里的关键还是CLIP,我之前曾经读了一点它的介绍,结果还是忘了。
    CLIP (Contrastive Language-Image Pre-Training) is a neural network trained on a variety of (image, text) pairs. It can be instructed in natural language to predict the most relevant text snippet, given an image, without directly optimizing for the task, similarly to the zero-shot capabilities of GPT-2 and 3.
    这里让我吃惊的是它似乎是反过来的,就是给一幅图它去预测文字,当然这个确实是我在webui里使用的用途,但是难道它训练的时候不是反过来的吗?难道不是给文字训练匹配图像,或者是计算两个向量的点乘吗?使用是训练的逆过程? 这幅示意图是写实的吗?文字和图片的向量似乎是组合成了一个矩阵,难道要选择所有的组合对子?但是我上面的理解是每一个token都是一个embedding,如果理解不错的话这个是多少个token就是多少个向量要怎么。。。 至少我学习了CLIP的缩写,这个也许是唯一理解的东西。
    A tokenizer can only tokenize words it has seen during training.
    这里透露的是它纯粹就是一个字典,或者说就是一个记忆模型,难怪我当时使用哪吒的三头六臂作为输入,结果模型完全不理解。因为训练材料是事先有筛选的。
  3. 这里我决定先实践一下CLIP,这里的安装指南要求合适的CUDA版本,我都不知道我是怎么装的,装在哪里?这里的办法最好就是使用nvidia-smi来查找:
    
    nick@nick-sager:~/workspace$ nvidia-smi
    Sun Feb 11 05:05:06 2024       
    +---------------------------------------------------------------------------------------+
    | NVIDIA-SMI 545.23.08              Driver Version: 545.23.08    CUDA Version: 12.3     |
    |-----------------------------------------+----------------------+----------------------+
    | GPU  Name                 Persistence-M | Bus-Id        Disp.A | Volatile Uncorr. ECC |
    | Fan  Temp   Perf          Pwr:Usage/Cap |         Memory-Usage | GPU-Util  Compute M. |
    |                                         |                      |               MIG M. |
    |=========================================+======================+======================|
    |   0  NVIDIA GeForce RTX 4050 ...    On  | 00000000:01:00.0 Off |                  N/A |
    | N/A   41C    P8               5W / 115W |    218MiB /  6141MiB |      0%      Default |
    |                                         |                      |                  N/A |
    +-----------------------------------------+----------------------+----------------------+
                                                                                             
    +---------------------------------------------------------------------------------------+
    | Processes:                                                                            |
    |  GPU   GI   CI        PID   Type   Process name                            GPU Memory |
    |        ID   ID                                                             Usage      |
    |=======================================================================================|
    |    0   N/A  N/A    137163      G   /usr/lib/xorg/Xorg                            4MiB |
    |    0   N/A  N/A    186449      C   python3                                     192MiB |
    +---------------------------------------------------------------------------------------+
    
    所以,我的版本是CUDA Version: 12.3,我的GPU型号是NVIDIA GeForce RTX 4050
  4. 我从来也不愿意学习python,总觉得是小孩子的玩意,但是现在不得不使用,只好学习hello world之类的,我想知道CLIP究竟有哪些模型,所以:
    
    import torch
    import clip
    
    print("models:", clip.available_models())
    
    使用这个API,我得到的运行结果是
    
    models: ['RN50', 'RN101', 'RN50x4', 'RN50x16', 'RN50x64', 'ViT-B/32', 'ViT-B/16', 'ViT-L/14', 'ViT-L/14@336px']
    
    至少我可以 尝试比较一下这几个模型的优劣吧,使用这个测试代码似乎很容易,尽管我的python基础是0
    
    import torch
    import clip
    from PIL import Image
    
    device = "cuda" if torch.cuda.is_available() else "cpu"
    model, preprocess = clip.load("ViT-B/32", device=device)
    
    image = preprocess(Image.open("CLIP.png")).unsqueeze(0).to(device)
    text = clip.tokenize(["a diagram", "a dog", "a cat"]).to(device)
    
    with torch.no_grad():
        image_features = model.encode_image(image)
        text_features = model.encode_text(text)
        
        logits_per_image, logits_per_text = model(image, text)
        probs = logits_per_image.softmax(dim=-1).cpu().numpy()
    
    print("Label probs:", probs)  # prints: [[0.9927937  0.00421068 0.00299572]]
    
    运行的结果如下:
    
    100%|████████████████████████████████████████| 338M/338M [07:53<00:00, 748kiB/s]
    Label probs: [[0.9927   0.004185 0.002968]]
    
    我不懂怎么下载模型,也不知道模型怎么保存,只好一个个模型尝试,就当是缓存了模型在本地。python的代码实际上是很容易理解的,基本猜出个八九不离十,它把这些模型都保存在本地的缓存出:~/.cache/clip/ 我决定统统下载这些模型
    
    _MODELS = {
        "RN50": "https://openaipublic.azureedge.net/clip/models/afeb0e10f9e5a86da6080e35cf09123aca3b358a0c3e3b6c78a7b63bc04b6762/RN50.pt",
        "RN101": "https://openaipublic.azureedge.net/clip/models/8fa8567bab74a42d41c5915025a8e4538c3bdbe8804a470a72f30b0d94fab599/RN101.pt",
        "RN50x4": "https://openaipublic.azureedge.net/clip/models/7e526bd135e493cef0776de27d5f42653e6b4c8bf9e0f653bb11773263205fdd/RN50x4.pt",
        "RN50x16": "https://openaipublic.azureedge.net/clip/models/52378b407f34354e150460fe41077663dd5b39c54cd0bfd2b27167a4a06ec9aa/RN50x16.pt",
        "RN50x64": "https://openaipublic.azureedge.net/clip/models/be1cfb55d75a9666199fb2206c106743da0f6468c9d327f3e0d0a543a9919d9c/RN50x64.pt",
        "ViT-B/32": "https://openaipublic.azureedge.net/clip/models/40d365715913c9da98579312b702a82c18be219cc2a73407c4526f58eba950af/ViT-B-32.pt",
        "ViT-B/16": "https://openaipublic.azureedge.net/clip/models/5806e77cd80f8b59890b7e101eabd078d9fb84e6937f9e85e4ecb61988df416f/ViT-B-16.pt",
        "ViT-L/14": "https://openaipublic.azureedge.net/clip/models/b8cca3fd41ae0c99ba7e8951adf17d267cdb84cd88be6f7c2e0eca1737a03836/ViT-L-14.pt",
        "ViT-L/14@336px": "https://openaipublic.azureedge.net/clip/models/3035c92b350959924f9f00213499208652fc7ea050643e8b385c2dac08641f02/ViT-L-14-336px.pt",
    }
    
    modela diagrama dog%a cat%
    RN500.9840.012980.003307
    RN1010.98930.006070.004726
    RN50x40.9720.018370.009384
    RN50x160.9050.084170.01087
    RN50x640.87740.094670.02798
    ViT-B/320.99270.0041850.002968
    ViT-B/160.76070.22840.01085
    ViT-L/140.94530.048550.005985
    ViT-L/14@336px0.9320.06290.00478
    除了这两个模型比较差以外其他似乎都还不错。对于这些API注解我觉得都是很初级的员工写的,反正开源的项目都是不挣钱的,比如这个怎么有乘以100呢?让我现在去理解这些算法还早的很,只不过我已经摸着了门径知道从哪里入手去找答案了。这就是我的进步。
  5. 总之,我们知道CLIP的确是有开放函数给你一幅图然后返回对应的text prompt的概率,也就是点乘的结果。不过这个能不能说给定多个图和一个text的结果呢?我不知道要怎么改代码,首先是这个图库很不错。
  6. 对于这个示例代码我不知道它下载的图片究竟是什么样子的,那么要怎么看看图片呢?我抄袭了一下这个代码。在原来代码基础上就是这么几行:
    
    import matplotlib.pyplot as plt
    
    # Prepare the inputs
    image, class_id = cifar100[3637]
    # we just show it with image loaded
    plt.imshow(image)
    plt.show()
    
    而对于普通的图片,本身就已经使用了这个库from PIL import Image 所以,可以直接调用它的显示函数。
    
    img = Image.open("my.png")
    img.show()
    
    我观察到另一个现象就是这些openAI的预训练模型非常的狭隘,就是说你给的text prompt超过两个词或者出现它不认识的token之类它就立刻崩溃了。它只能非常简单的识别诸如a man, a woman之类,但凡多一个形容词就不认识了。
  7. 我不妨尝试一下open-clip

二月十二日 等待变化等待机会

  1. 我对于clip的简单的实验得出一个简单的结论就是它还不是很稳定,比如,同样一幅图,让它测试看a cat, a dog, a diagram的标准表现的很不错,如果把a diagram换成a panda结果是毛和狗的比例都上升了,这个也许是有道理的,可是在我看来返回的总概率是100%本身这个做法就是强人所难,三个都不是怎么办?其次,就是如果我多几个text prompt,结果都不对了。
  2. open clip支持的模型多得多:
    
    import open_clip
    open_clip.list_pretrained()
    
    [('RN50', 'openai'), ('RN50', 'yfcc15m'), ('RN50', 'cc12m'), ('RN50-quickgelu', 'openai'), ('RN50-quickgelu', 'yfcc15m'), ('RN50-quickgelu', 'cc12m'), ('RN101', 'openai'), ('RN101', 'yfcc15m'), ('RN101-quickgelu', 'openai'), ('RN101-quickgelu', 'yfcc15m'), ('RN50x4', 'openai'), ('RN50x16', 'openai'), ('RN50x64', 'openai'), ('ViT-B-32', 'openai'), ('ViT-B-32', 'laion400m_e31'), ('ViT-B-32', 'laion400m_e32'), ('ViT-B-32', 'laion2b_e16'), ('ViT-B-32', 'laion2b_s34b_b79k'), ('ViT-B-32', 'datacomp_xl_s13b_b90k'), ('ViT-B-32', 'datacomp_m_s128m_b4k'), ('ViT-B-32', 'commonpool_m_clip_s128m_b4k'), ('ViT-B-32', 'commonpool_m_laion_s128m_b4k'), ('ViT-B-32', 'commonpool_m_image_s128m_b4k'), ('ViT-B-32', 'commonpool_m_text_s128m_b4k'), ('ViT-B-32', 'commonpool_m_basic_s128m_b4k'), ('ViT-B-32', 'commonpool_m_s128m_b4k'), ('ViT-B-32', 'datacomp_s_s13m_b4k'), ('ViT-B-32', 'commonpool_s_clip_s13m_b4k'), ('ViT-B-32', 'commonpool_s_laion_s13m_b4k'), ('ViT-B-32', 'commonpool_s_image_s13m_b4k'), ('ViT-B-32', 'commonpool_s_text_s13m_b4k'), ('ViT-B-32', 'commonpool_s_basic_s13m_b4k'), ('ViT-B-32', 'commonpool_s_s13m_b4k'), ('ViT-B-32-256', 'datacomp_s34b_b86k'), ('ViT-B-32-quickgelu', 'openai'), ('ViT-B-32-quickgelu', 'laion400m_e31'), ('ViT-B-32-quickgelu', 'laion400m_e32'), ('ViT-B-32-quickgelu', 'metaclip_400m'), ('ViT-B-32-quickgelu', 'metaclip_fullcc'), ('ViT-B-16', 'openai'), ('ViT-B-16', 'laion400m_e31'), ('ViT-B-16', 'laion400m_e32'), ('ViT-B-16', 'laion2b_s34b_b88k'), ('ViT-B-16', 'datacomp_xl_s13b_b90k'), ('ViT-B-16', 'datacomp_l_s1b_b8k'), ('ViT-B-16', 'commonpool_l_clip_s1b_b8k'), ('ViT-B-16', 'commonpool_l_laion_s1b_b8k'), ('ViT-B-16', 'commonpool_l_image_s1b_b8k'), ('ViT-B-16', 'commonpool_l_text_s1b_b8k'), ('ViT-B-16', 'commonpool_l_basic_s1b_b8k'), ('ViT-B-16', 'commonpool_l_s1b_b8k'), ('ViT-B-16', 'dfn2b'), ('ViT-B-16-quickgelu', 'metaclip_400m'), ('ViT-B-16-quickgelu', 'metaclip_fullcc'), ('ViT-B-16-plus-240', 'laion400m_e31'), ('ViT-B-16-plus-240', 'laion400m_e32'), ('ViT-L-14', 'openai'), ('ViT-L-14', 'laion400m_e31'), ('ViT-L-14', 'laion400m_e32'), ('ViT-L-14', 'laion2b_s32b_b82k'), ('ViT-L-14', 'datacomp_xl_s13b_b90k'), ('ViT-L-14', 'commonpool_xl_clip_s13b_b90k'), ('ViT-L-14', 'commonpool_xl_laion_s13b_b90k'), ('ViT-L-14', 'commonpool_xl_s13b_b90k'), ('ViT-L-14-quickgelu', 'metaclip_400m'), ('ViT-L-14-quickgelu', 'metaclip_fullcc'), ('ViT-L-14-quickgelu', 'dfn2b'), ('ViT-L-14-336', 'openai'), ('ViT-H-14', 'laion2b_s32b_b79k'), ('ViT-H-14-quickgelu', 'metaclip_fullcc'), ('ViT-H-14-quickgelu', 'dfn5b'), ('ViT-H-14-378-quickgelu', 'dfn5b'), ('ViT-g-14', 'laion2b_s12b_b42k'), ('ViT-g-14', 'laion2b_s34b_b88k'), ('ViT-bigG-14', 'laion2b_s39b_b160k'), ('roberta-ViT-B-32', 'laion2b_s12b_b32k'), ('xlm-roberta-base-ViT-B-32', 'laion5b_s13b_b90k'), ('xlm-roberta-large-ViT-H-14', 'frozen_laion5b_s13b_b90k'), ('convnext_base', 'laion400m_s13b_b51k'), ('convnext_base_w', 'laion2b_s13b_b82k'), ('convnext_base_w', 'laion2b_s13b_b82k_augreg'), ('convnext_base_w', 'laion_aesthetic_s13b_b82k'), ('convnext_base_w_320', 'laion_aesthetic_s13b_b82k'), ('convnext_base_w_320', 'laion_aesthetic_s13b_b82k_augreg'), ('convnext_large_d', 'laion2b_s26b_b102k_augreg'), ('convnext_large_d_320', 'laion2b_s29b_b131k_ft'), ('convnext_large_d_320', 'laion2b_s29b_b131k_ft_soup'), ('convnext_xxlarge', 'laion2b_s34b_b82k_augreg'), ('convnext_xxlarge', 'laion2b_s34b_b82k_augreg_rewind'), ('convnext_xxlarge', 'laion2b_s34b_b82k_augreg_soup'), ('coca_ViT-B-32', 'laion2b_s13b_b90k'), ('coca_ViT-B-32', 'mscoco_finetuned_laion2b_s13b_b90k'), ('coca_ViT-L-14', 'laion2b_s13b_b90k'), ('coca_ViT-L-14', 'mscoco_finetuned_laion2b_s13b_b90k'), ('EVA01-g-14', 'laion400m_s11b_b41k'), ('EVA01-g-14-plus', 'merged2b_s11b_b114k'), ('EVA02-B-16', 'merged2b_s8b_b131k'), ('EVA02-L-14', 'merged2b_s4b_b131k'), ('EVA02-L-14-336', 'merged2b_s6b_b61k'), ('EVA02-E-14', 'laion2b_s4b_b115k'), ('EVA02-E-14-plus', 'laion2b_s9b_b144k'), ('ViT-B-16-SigLIP', 'webli'), ('ViT-B-16-SigLIP-256', 'webli'), ('ViT-B-16-SigLIP-i18n-256', 'webli'), ('ViT-B-16-SigLIP-384', 'webli'), ('ViT-B-16-SigLIP-512', 'webli'), ('ViT-L-16-SigLIP-256', 'webli'), ('ViT-L-16-SigLIP-384', 'webli'), ('ViT-SO400M-14-SigLIP', 'webli'), ('ViT-SO400M-14-SigLIP-384', 'webli'), ('ViT-L-14-CLIPA', 'datacomp1b'), ('ViT-L-14-CLIPA-336', 'datacomp1b'), ('ViT-H-14-CLIPA', 'datacomp1b'), ('ViT-H-14-CLIPA-336', 'laion2b'), ('ViT-H-14-CLIPA-336', 'datacomp1b'), ('ViT-bigG-14-CLIPA', 'datacomp1b'), ('ViT-bigG-14-CLIPA-336', 'datacomp1b'), ('nllb-clip-base', 'v1'), ('nllb-clip-large', 'v1'), ('nllb-clip-base-siglip', 'v1'), ('nllb-clip-large-siglip', 'v1')]
    问题是这些模型和这个对不起来。也许是一大类的模型的规格吧?
    也许这些模型的规格是有用的吧,我决定存一个拷贝。
    1
    modelimage_sizeimage_widthtext_widthembed_dimmparamsimage_mparamstext_mparamsgflopsimage_gflopstext_gflops
    2
    ViT-S-32-alt22438425625643.2222.5920.633.562.291.27
    3
    ViT-S-3222438438438463.0922.6440.445.662.293.38
    4
    ViT-M-32-alt22451238438480.0739.6340.447.373.993.38
    5
    ViT-M-32224512512512103.1239.6963.439.953.995.96
    6
    ViT-S-16-alt22438425625642.421.7620.6310.479.21.27
    7
    ViT-S-1622438438438462.2621.8140.4412.589.23.38
    8
    ViT-B-32224768512512151.2887.8563.4314.788.825.96
    9
    ViT-B-32-quickgelu224768512512151.2887.8563.4314.788.825.96
    10
    convnext_tiny224768512102492.328.6163.6914.878.915.96
    11
    ViT-B-32-256256768512512151.2987.8663.4317.4611.55.96
    12
    RN50224645121024102.0138.3263.6918.1812.225.96
    13
    RN50-quickgelu224645121024102.0138.3263.6918.1812.225.96
    14
    ViT-M-16-alt22451238438478.9838.5340.4419.3615.983.38
    15
    ViT-M-16224512512512102.0238.5963.4321.9415.985.96
    16
    vit_relpos_medium_patch16_cls_224224768512512101.9438.5163.4321.9916.035.96
    17
    mt5-base-ViT-B-32224768512512365.7187.85277.8622.128.8213.3
    18
    convnext_small224768512512113.2849.8563.4323.3317.375.96
    19
    ViT-B-32-plus-256256896640640210.3119.1391.1624.8315.569.27
    20
    RN10122464512512119.6956.2663.4325.519.545.96
    21
    RN101-quickgelu22464512512119.6956.2663.4325.519.545.96
    22
    vit_medium_patch16_gap_256256768512512102.0438.6163.4327.121.145.96
    23
    coca_ViT-B-32224768512512253.5689.1663.4333.349.195.96
    24
    convnext_base224768512512151.5288.0963.4336.6730.715.96
    25
    swin_base_patch4_window7_224224768640640178.5687.491.1640.1330.869.27
    26
    ViT-B-16224768512512149.6286.1963.4341.0935.135.96
    27
    ViT-B-16-quickgelu224768512512149.6286.1963.4341.0935.135.96
    28
    EVA02-B-16224768512512149.6986.2663.4341.0935.135.96
    29
    ViT-B-16-SigLIP224768768768203.1692.88110.2746.4435.4211.02
    30
    convnext_base_w256768640640179.3988.2291.1649.3840.119.27
    31
    RN50x428880640640178.387.1491.1651.8242.569.27
    32
    coca_roberta-ViT-B-32224768768512420.3787.85124.4553.128.8213.12
    33
    ViT-B-16-plus224896640640208.35117.1991.1656.7547.499.27
    34
    ViT-B-16-SigLIP-256256768768768203.292.93110.2757.8446.8211.02
    35
    ViT-B-16-SigLIP-i18n-256256768768768370.6392.93277.757.8446.8211.02
    36
    ViT-B-16-plus-240240896640640208.38117.2191.1664.0354.769.27
    37
    convnext_base_w_320320768640640179.3988.2291.1671.9462.679.27
    38
    convnext_large224768768768321.06197.41123.6582.0268.7213.3
    39
    coca_base288768768512440.3486.4134.6699.0946.4713.3
    40
    roberta-ViT-B-32224768512512212.7287.85124.87105.878.8297.05
    41
    xlm-roberta-base-ViT-B-32224768512512366.1287.85278.27105.878.8297.05
    42
    convnext_large_d256768768768351.77199.77152.0107.589.7617.73
    43
    ViT-B-16-SigLIP-384384768768768203.4593.18110.27123.15112.1311.02
    44
    ViT-L-162241024768768427.74304.09123.65136.41123.1113.3
    45
    convnext_large_d_320320768768768351.77199.77152.0157.98140.2517.73
    46
    RN50x1638496768768290.98167.33123.65162.69149.3913.3
    47
    ViT-L-14-CLIPA2241024768768414.21303.96110.25167.5162.035.47
    48
    EVA02-L-14224768768768427.76304.11123.65175.3162.013.3
    49
    ViT-L-142241024768768427.62303.97123.65175.33162.0313.3
    50
    ViT-L-14-quickgelu2241024768768427.62303.97123.65175.33162.0313.3
    51
    convnext_xlarge25676810241024653.89350.25303.65198.38159.1439.24
    52
    ViT-L-16-SigLIP-25625676810241024652.15315.96336.19201.62162.5639.06
    53
    coca_ViT-L-142241024768768638.45306.72123.65214.52163.6413.3
    54
    ViT-B-16-SigLIP-512512768768768203.7993.52110.27227.26216.2411.02
    55
    ViT-SO400M-14-SigLIP22476811521152877.36427.68449.68233.54220.3513.19
    56
    ViT-L-14-2802801024768768427.76304.11123.65271.79258.4913.3
    57
    ViT-L-16-3203201024768768427.95304.3123.65271.93258.6313.3
    58
    ViT-H-16224128010241024986.26632.23354.03301.72254.6347.09
    59
    ViT-H-14-CLIPA224128010241024968.24632.07336.16354.02334.5919.43
    60
    nllb-clip-base224768512512501.8987.85414.04369.68.82360.78
    61
    ViT-H-14224128010241024986.11632.08354.03381.68334.5947.09
    62
    ViT-H-14-quickgelu224128010241024986.11632.08354.03381.68334.5947.09
    63
    ViT-L-14-CLIPA-3363361024768768414.54304.29110.25387.39381.925.47
    64
    EVA02-L-14-336336768768768428.08304.43123.65395.16381.8613.3
    65
    ViT-L-14-3363361024768768427.94304.29123.65395.22381.9213.3
    66
    ViT-L-16-SigLIP-38438476810241024652.48316.28336.19422.91383.8539.06
    67
    convnext_xxlarge256768102410241200.58846.54354.03443.03395.9447.09
    68
    nllb-clip-base-siglip384768512768507.4793.18414.3472.91112.13360.78
    69
    mt5-xl-ViT-H-14224128051210242306.75632.081674.68514.04334.59179.45
    70
    EVA01-g-1422476876810241136.441012.59123.85547.36534.0613.3
    71
    RN50x6444812810241024623.26420.38202.88552.65529.1123.55
    72
    EVA01-g-14-plus224768102410241366.621012.59354.03581.15534.0647.09
    73
    ViT-g-142241408102410241366.681012.65354.03581.15534.0647.09
    74
    convnext_xxlarge_320320768102410241200.58846.54354.03665.74618.6547.09
    75
    xlm-roberta-large-ViT-H-14224128051210241193.01632.08560.94671.01334.59336.42
    76
    ViT-SO400M-14-SigLIP-38438476811521152877.96428.23449.73723.48670.3553.13
    77
    ViT-H-14-CLIPA-336336128010241024968.64632.48336.16800.88781.4519.43
    78
    ViT-bigG-14-CLIPA2241664128012802517.221844.9672.321007.93967.540.44
    79
    ViT-H-14-378-quickgelu378128010241024986.71632.68354.031054.051006.9647.09
    80
    ViT-bigG-142241664128012802539.571844.91694.661065.36967.597.86
    81
    nllb-clip-large224128051210241399.22632.08767.141468.46334.591133.87
    82
    nllb-clip-large-siglip38476851211521195.5428.23767.271804.22670.351133.87
    83
    ViT-e-142241792128012804581.093807.72773.372091.451981.35110.1
    84
    ViT-bigG-14-CLIPA-3363361664128012802517.761845.44672.322271.582231.1540.44
    85
    EVA02-E-14224768102410244704.594350.56354.032311.422264.3347.09
    86
    EVA02-E-14-plus224768128010245044.894350.56694.332362.192264.3397.86
    从这个代码我猜想两个参数和clip是一样的就是模型名称
  3. 我从cdn-lfs.huggingface.co的ssh下载老是出错让我怀疑是否我有ssh-key没有setup的问题?问题这里检验我ssh访问应该是没有问题的
    
    ssh -T git@hf.co
    
    其实,我大概也能猜出来这个的确是伟光正网络的问题,但是我还是不太甘心。
  4. 遭遇了重大的挫折,就是我重启之后完全无法进入图形界面。按照经验肯定是nvidia的驱动在内核升级后的种种不兼容造成的。但是这里有几个问题:
    1. 首先,我希望进入ubuntu的grub启动菜单的高级模式以便修复。这个在bios模式下是shift按键,而uefi下是esc按键。而要进入我的笔记本的bios模式需要的是F2。这些我全都忘记了。
    2. 如果要固定显示启动的高级菜单,需要修改etc/default/grub里的
      
      #GRUB_TIMEOUT_STYLE=hidden
      GRUB_TIMEOUT=5
      
    3. 那么完全无法登陆很明显是显卡的初始化的问题吧?于是只能完全卸载NVIDIA的驱动,比如
      
      sudo apt-get purge "^nvidia-*"
      sudo apt-get purge "^libnvidia*" "^libcuda*"
      
      关于如何安装nvidia官方驱动,我以为我有笔记,结果书到用时方恨少,发现我居然没有!这里是下载的链接
    4. 但是官方的驱动并不是好的解决办法,因为安装需要编译内核模块,而这个混蛋居然要求编译器gcc-12,否则会有很多错误。我在ubuntu 22.04,手动安装gcc-12并不现实,因为不支持,除非你自己编译,这个时候我是在ubuntu的高级启动菜单里的root shell,怎么可能呢?所以,变成需要使用Ubuntu官方编译好的驱动。
      
      nick@nick-sager:~$ ubuntu-drivers devices
      == /sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0 ==
      modalias : pci:v000010DEd000028A1sv00001558sd0000A650bc03sc00i00
      vendor   : NVIDIA Corporation
      driver   : nvidia-driver-535-server-open - distro non-free
      driver   : nvidia-driver-545-open - distro non-free
      driver   : nvidia-driver-525-open - distro non-free
      driver   : nvidia-driver-545 - third-party non-free
      driver   : nvidia-driver-525-server - distro non-free
      driver   : nvidia-driver-535 - third-party non-free
      driver   : nvidia-driver-525 - third-party non-free
      driver   : nvidia-driver-550 - third-party non-free recommended
      driver   : nvidia-driver-550-open - third-party non-free
      driver   : nvidia-driver-535-server - distro non-free
      driver   : nvidia-driver-530 - third-party non-free
      driver   : nvidia-driver-535-open - distro non-free
      driver   : xserver-xorg-video-nouveau - distro free builtin
      
      我选择安装最新的nvidia-driver-550驱动。
    5. 但是你以为着就算安成你就又错了,因为似乎没有人去更新grub,我模糊记得编译驱动会调用update-initramfs,但是似乎没有更新grub,update-grub2。总之,重启又是黑屏,这个时候已经不再是完全没有登陆界面,而是可以login,但是登录后就黑屏,这个说明只是桌面的问题。我可以使用ctl-alt-F4登陆来查看系统。
    6. 这个中间还有一个插曲就是我只好用手机下载安装程序,结果没有在存储界面安全弹出USB导致文件拷贝不全被安装程序的签名检查发现。总之,实在是太痛苦了。以后要怎么安装nvida的驱动呢?
  5. 我终于明白我从huggingface.co之类的下载预处理模型的代码调用的是huggingface_hub这个模块,而它可以在命令行工具里使用huggingface-cli,所以,我的问题可以在这个复现
    
    huggingface-cli download gpt2 config.json
    
    我决定按照这个指导来安装虚拟环境。实际上这个都是徒劳,看一下新闻就知道是为光正不知道为何把它封了,我觉得说不定是国内的AI公司在使坏。 这个大神使用镜像可能是唯一可行的。
    
    export HF_ENDPOINT=https://hf-mirror.com
    python -c "from huggingface_hub import model_info; print(model_info('gpt2'))"
    
    为了打印好看也许在浮点数后面加上.numpy()能有些帮助吧?
  6. 这个clip-retrieval也许是一个不错的工具。怎么用我还不清楚,但是看上去不错的。
  7. 这里有提到一个快速DNS的方案,我决定试一下。这里是官方的指引,我懒得看,就直接按照ubuntu的命令来吧:
    
    wget https://secure.nic.cz/files/knot-resolver/knot-resolver-release.deb
    sudo dpkg -i knot-resolver-release.deb
    sudo apt update
    sudo apt install -y knot-resolver
    sudo sh -c 'echo `hostname -I` `hostname` >> /etc/hosts'
    sudo sh -c 'echo nameserver 127.0.0.1 > /etc/resolv.conf'
    sudo systemctl stop systemd-resolved
    
    我因为已经有bind9了所以,不能立即启动knot,只有停掉它再启动knot之后修改配置又可以了。总之我是在云里雾里完全不知道在干什么。到底工作不工作也不知道。
  8. 我至今不会怎么在synology里设置nfs mount的权限,只好每次都login去修改/etc/exportfs里
    
    /volume1/photo  *(rw,async,no_wdelay,crossmnt,all_squash,insecure_locks,sec=sys,anonuid=1025,anongid=100)
    /volume1/music  *(rw,async,no_wdelay,crossmnt,all_squash,insecure_locks,sec=sys,anonuid=1025,anongid=100)
    /volume1/video  *(rw,async,no_wdelay,crossmnt,all_squash,insecure_locks,sec=sys,anonuid=1024,anongid=100)
    
    然后再exportfs -a去更新,否则我local mount权限不够。真是惭愧,我居然连最基本的nfs也没有搞明白,算是白在HDS待了这些年了。
  9. 这个看起来是不明觉厉的帖子,我现在始终搞不懂我的DNS是怎么回事。这个问题太复杂了,我记录下这个关于vpn的链接供以后查询吧。我实在是搞得焦头烂额。
  10. 我打算尝试一下这个img2dataset的mscoco例子:
    
    wget https://huggingface.co/datasets/ChristophSchuhmann/MS_COCO_2017_URL_TEXT/resolve/main/mscoco.parquet
    img2dataset --url_list mscoco.parquet --input_format "parquet"\
             --url_col "URL" --caption_col "TEXT" --output_format webdataset\
               --output_folder mscoco --processes_count 16 --thread_count 64 --image_size 256\
                 --enable_wandb False
    
    我遇到一些wandb的错误,索性就把它设为false。作者提到一个很酷的观察带宽的工具:bwm-ng 它下载的结果是下载了一系列的.parequest文件,这个应该是某种二进制的链接及其说明文件,依靠它再成功下载一个.tar文件,它包含了图片以及对应的说明文字.txt和结构化说明文件.json。这个以后可以作参考。

二月十三日 等待变化等待机会

  1. 似乎在nfs mount里tree不工作,那么如果仅仅想知道繁杂的目录结构的话,我们最简单的朋友find,就能做得很好:
    
    find . -type d  -not -path '*/\.*'
    
    这个是只显示目录,针对各个类型文件那就更容易的,比tree来的容易的多,只不过tree画图实在是个硬功夫!
  2. 感觉我的战线拉的太长了,到底我在解决vpn的问题还是在学习openClip的使用,抑或是stable diffusion的步骤,中间因为安装nvidia驱动导致的一系列显示和内核编译带来的问题?到底哪一个方向呢?也许还是要从基础开始,不然困扰我的网络问题无时无刻都在,这个基础问题不彻底解决真的是永无宁日,但是我不明白的是为什么我使用了vpn还是被限制,照理说我已经跳出三界外,不在五行中,难道是因为我的DNS/routing导致所谓的split DNS的问题,要么我全部都依赖vpn的DNS,一切都从海外,国内慢一些也无妨?问题是这个问题是否有解?为什么防火墙能够阻挡我?我有没有可能使用ec2上的DNS解析?我到达ec2不也是要我本地的DNS指路才行吗?这个基本的过程我始终不清楚,还有就是ec2上我为什么不能使用ssh+x11远程显示?
  3. 首先从最最容易的入手,那就是我自己本机的ssh-key代替/平替亚马逊的,这个本来是很容易的,只不过我担心有什么猫腻,专门查看sshd_config,后来才想到这个是ubuntu image提供的和亚马逊无关,而在/home/openvpnas/.ssh里的pubkey本来就是我给亚马逊的,所以,这个没有任何悬念,我本机的ssh-pubkey去concat还是并行设为authorized_keys2呢?这个我通过改变sshd_config的log level到DEBUG然后看/var/log/auth.log来看到sshd是两个文件都找一遍,虽然注解上说也许将来后者有可能放弃。总之这个问题解决了,我省的每次都要多加一个亚马逊的key。
  4. 第二个小问题也解决了,首先,我要明确xclock这种验证程序是工作的,那么其次使用firefox失败的错误X11 connection rejected because of wrong authentication.就是个别应用的,所以,这个帖子是解决办法。
    
    export XAUTHORITY=$HOME/.Xauthority 
    firefox
    
    当然这个仅仅是一个验证,因为带宽需要太大了,完全无法使用,这个还不如使用远程的rdp之类的。
  5. 那么当前的重点还是解决VPN的split DNS问题,或许仔细阅读这个是个入门。

二月十四日 等待变化等待机会

  1. 我的笔记本的第二个ssd的mount要记录一下:
    
    /dev/disk/by-uuid/9343f884-54dc-481f-a702-9a74ca0e025f /home/nick/workspace auto nosuid,nodev,nofail,x-gvfs-show,x-gvfs-name=fanxiang 0 0
    
    其中的选项nosuid,nodev,nofail,x-gvfs-show,x-gvfs-name=fanxiang值得重视。
  2. 早晨看到apparmor的配置文件/etc/apparmor.d/感觉这一套体系非常的复杂,希望我不要遇到这类问题。
  3. 我的感觉这篇博文是我寻找了很久的指引。最起码这个开宗明义的定义问题就是我想说却说不出来的东西:

    Let’s first define two distinct VPN use-cases:

    1. Corporate VPNs, i.e. VPNs that open access to a specific set of additional hosts. Only specific domains should be resolved via the VPN’s DNS servers, and everything that is not related to the company’s domain names should go to regular, non-VPN DNS instead.

    2. Privacy VPNs, i.e. VPNs that should be used for basically all DNS traffic, once they are up. If this type of VPN is used, any regular, non-VPN DNS servers should not get any traffic anymore.

    大多数在公司上班的人不认为VPN配置有什么问题的都是第一种在公司远程上班的,因为你的普通家用的DNS也不知道公司防火墙后面有什么,你毫不费力的转向了VPN的DNS来询问,而我的情况是比以上两种都复杂的情况,明明家里普通的DNS都能找到的外网路径我不能使用,需要指明使用VPN的专项路径,同时国内网络我又不想绕到国外去转一大圈,结果就是一个混乱的解决。也许我完全采用第二种就是放弃内网的访问效率就是一个简单的解决?
    这里接下去介绍的三种配置思路让我头疼不已,非常的难懂,因为我的网络知识非常的有限,对于search domain和routing domain的异同始终不能理解。也许看到最后的实作才能有所顿悟吧?

    Then, let’s briefly introduce three DNS routing concepts that software managing a network interface may configure.

    1. Search domains: these are traditional DNS configuration parameters and are used to suffix non-qualified domain names (i.e. single-label ones), to turn them into fully qualified domain names. Traditionally (before systemd-resolved.service), search domain names are attached to a system’s IP configuration as a whole, in systemd-resolved.service they are associated to individual interfaces instead, since they are typically acquired through some network associated concept, such as a DHCP, IPv6RA or PPP lease. Most importantly though: in systemd-resolved.service they are not just used to suffix single-label domain names, but also for routing domain name lookups: if a network interface has a search domain foo.com configured on it, then any lookups for names ending in .foo.com (or for foo.com itself) are preferably routed to the DNS servers configured on the same network interface.

    2. Routing domains: these are very similar to search domains, but are purely about DNS domain name lookup routing — they are not used for qualifying single-label domain names. When it comes to routing, assigning a routing domain to a network interface is identical to assigning a search domain to it.

      Why the need to have both concepts, i.e. search and routing domains? Mostly because in many cases the qualifying of single-label names is not desirable (as it has security implications), but needs to be supported for specific use-cases. Routing domains are a concept systemd-resolved.service introduced, while search domains are traditionally available and are part of DHCP/IPv6RA/PPP leases and thus universally supported. In many cases routing domains are probably the more appropriate concept, but not easily available, since they are not part of DHCP/IPv6RA/PPP.

      Routing domains for systemd-resolved.service are usually presented along with search domains in mostly the same way, but prefixed with ~ to differentiate them. i.e. ~foo.com is a configured routing domain, while foo.com would be a configured search domain.

      One routing domain is particularly interesting: ~. — the catch-all routing domain. (The dot domain . is how DNS denotes the “root” domain, i.e. the parent domain of all domains, but itself.) When used on an interface any DNS traffic is preferably routed to its DNS servers. (A search domain – i.e. . instead of ~. — would have the same effect, but given that it’s mostly pointless to suffix an unqualified domain with ., we generally declare it as a routing domain, not a search domain).

      Routing domains also have particular relevance when it comes to the reverse lookup DNS domains .in-addr.arpa and .ip6.arpa. An interface that has these (or sub-domains thereof) defined as routing domains, will be preferably used for doing reverse IP to domain name lookups. e.g. declaring ~168.192.in-addr.arpa on an interface means that all lookups to find the domain names for IPv4 addresses 192.168.x.y are preferably routed to it.

    3. The default-route boolean. This is a simple boolean value that may be set on an interface. If true (the default), any DNS lookups for which no matching routing or search domains are defined are routed to interfaces marked like this. If false then the DNS servers on this interface are not considered for routing lookups to except for the ones listed in the search/routing domain list. An interface that has no search/routing domain associated and also has this boolean off is not considered for any lookups.

    这里马上就暴露出了我的无知,我对于FQDN看了多少回也不知道它真正的含义:

    What is a fully qualified domain name (FQDN)?

    A fully qualified domain name (FQDN) is the complete address of an internet host or computer. It provides its exact location within the domain name system (DNS) by specifying the hostname, domain name and top-level domain (TLD). For example, for the domain name www.whatis.com, "www" is the hostname, "whatis" is the domain name and ".com" is the top-level domain.

    那么接下去的常识就是FQDN和URL的关系:
    An FQDN doesn't carry the TCP/IP protocol information -- such as Hypertext Transfer Protocol (HTTP) or Hypertext Transfer Protocol Secure (HTTPS) -- which is always used at the beginning of a URL. Therefore, adding the prefix http:// or https:// to the FQDN turns it into a full URL. Also, URLs can specify directory paths, file names and TCP port numbers, which FQDNs don't include.
    URL可以称之为FQDN的一个超集,它完全包含了并且还可以额外提供协议以及端口。更进一步就是A PQDN is part of an FQDN that isn't fully specified.

二月十五日 等待变化等待机会

  1. 这篇文章我读了但是依然不明所以然,我只能祈求使用实例来帮助理解,比如我首先要设置systemd-resolved的log
    
    sudo resolvectl log-level debug
    journalctl -f -u systemd-resolved.service
    dig www.google.com
    
    然后我就可以观察到DNS解析的每一步了。至少我现在观察到在chromium里为什么不能使用google搜索是因为它总是在问www.googleapis.com的解析,和www.google.com的解析结果不同,googleapis.com返回了更大uo的结果(我只保留了answer部分)
    
    nick@nick-sager:~$ dig www.googleapis.com
    
    ;; ANSWER SECTION:
    www.googleapis.com.	400	IN	A	172.217.160.106
    www.googleapis.com.	400	IN	A	172.217.163.42
    www.googleapis.com.	400	IN	A	142.251.42.234
    www.googleapis.com.	400	IN	A	142.251.43.10
    www.googleapis.com.	400	IN	A	172.217.160.74
    
    对比一下
    
    nick@nick-sager:~$ dig www.google.com
    
    ;; ANSWER SECTION:
    www.google.com.		600	IN	A	154.83.14.134
    
  2. 在我进一步作实验以前我想再读一下这篇文章。遥想了解现在,你必须先了解历史!

    Traditional DNS with nss-dns

    There are two important configuration files to discuss. The first is /etc/nsswitch.conf, which controls which NSS modules are invoked by glibc when performing name resolution.

    Next, let’s look at /etc/resolv.conf. This file contains a list of up to three DNS servers to use. The servers are attempted in order. If the first server in the list is broken, then the second server will be used. If the second server is broken, the third server will be used. If the third server is also broken, then everything fails, because no matter how many servers you list here, all except the first three are ignored.

    Traditional DNS Problems

    Traditional DNS is all well and good for a simple case like we had above, but turns out it’s really broken once you start adding VPNs to the mix.

    总而言之,它说到了split DNS的使用场景,我觉得是非常精准的契合我的情况,而这样的传统的DNS解决方案无法分清楚,因为从glibc模块的解决法就是第一个失败了找第二个,然后第三个,最后失败。因为它不清楚这些有着不同意义的解析。但是作者讨论的是Fedora,也许和Ubuntu有些不同,我的是这样子的
    
    hosts:          files mdns4_minimal [NOTFOUND=return] resolve [!UNAVAIL=return] dns mymachines
    
    不过他这里讨论的NSS-DNS是另一个纬度的问题吧? 比如我的DNS是每一个网卡都有的吗?
    
    nick@nick-sager:~$ resolvectl status
    Global
           Protocols: -LLMNR -mDNS DNSOverTLS=opportunistic DNSSEC=no/unsupported
    resolv.conf mode: stub
    
    Link 2 (enp0s31f6)
        Current Scopes: DNS
             Protocols: +DefaultRoute +LLMNR -mDNS DNSOverTLS=opportunistic DNSSEC=no/unsupported
    Current DNS Server: fe80::1
           DNS Servers: 8.8.8.8 218.85.152.99 218.85.157.99 fe80::1%32544
    
    Link 3 (wlp109s0)
    Current Scopes: none
         Protocols: -DefaultRoute +LLMNR -mDNS DNSOverTLS=opportunistic DNSSEC=no/unsupported
    
    Link 9 (tun0)
    Current Scopes: none
         Protocols: -DefaultRoute +LLMNR -mDNS DNSOverTLS=opportunistic DNSSEC=no/unsupported
    
    我看不到我的VPN创建的tun0有解析的功能,这个在那里设置的?
    Although systemd-resolved supports several different modes for managing /etc/resolv.conf, the default mode, and the mode used in both Fedora and Ubuntu, is for /etc/resolv.conf to be a symlink to /run/systemd/resolve/stub-resolv.conf.
    这个结论还是很重要的,就是nss-dns只有在systemd-resolved不工作才起作用,而这个
    
    nick@nick-sager:/etc$ ll /run/systemd/resolve/stub-resolv.conf
    -rw-r--r-- 1 systemd-resolve systemd-resolve 920 Feb 12 18:27 /run/systemd/resolve/stub-resolv.conf
    nick@nick-sager:/etc$ ll /etc/resolv.conf 
    lrwxrwxrwx 1 root root 39 Mar 31  2023 /etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf
    
    目前在ubuntu,的确是
    /etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf
    我的理解是这个stbu-resolve等价于127.0.0.53。
    systemd-resolved provides a local DNS stub listener on the IP addresses 127.0.0.53 and 127.0.0.54 on the local loopback interface. Programs issuing DNS requests directly, bypassing any local API may be directed to this stub, in order to connect them to systemd-resolved. Note however that it is strongly recommended that local programs use the glibc NSS or bus APIs instead (as described above), as various network resolution concepts (such as link-local addressing, or LLMNR Unicode domains) cannot be mapped to the unicast DNS protocol.
    这个man page是非常的难懂,因为背景知识的缺失,我对于D-bus始终不理解

    A Word about Ubuntu

    Although Ubuntu has used systemd-resolved for four years now, it has not switched from nss-dns to nss-resolve, contrary to upstream recommendations. This means that on Ubuntu, glibc still reads /etc/resolv.conf, finds 127.0.0.53 listed there, and then makes an IP connection to systemd-resolved rather than talking to it via varlink or D-Bus, as occurs on Fedora. The practical effect is that, on Ubuntu, you can still manually edit /etc/resolv.conf and applications will respond to those changes, unlike Fedora.

  3. 这一段很重要因为我作为一个普通人也是有这种混淆,一提到routing,想到的都是IP routing,而不是这里的DNS routing

    IP Routing Domains, DNS Routing Domains, and DNS Search Domains: Oh My!

    systemd-resolved works with DNS routing domains and DNS search domains. A DNS routing domain determines only which DNS server your DNS query goes to.  It doesn’t determine where IP traffic goes to: that would be an IP routing domain. Normally, when people talk about “routing domains,” they probably mean IP routing domains, not DNS routing domains, so be careful not to confuse these two concepts.

    这里非常完美的回答了我另一个疑问domain search和domain routing的区别
    A DNS search domain is also different. When you query a name that is only a single labela domain without any dots — a search domain gets appended to your query.
    这段也是很重要的,这个tilde(~)是区别于search domain和routing domain的标志:
    In systemd-resolved, each DNS routing domain may or may not be used as a search domain. By default, systemd-resolved will add search domains for every configured routing domain that is not prefixed by a tilde. For example, ~example.com is a routing domain only, while example.com is both a routing domain and a search domain. There is also a global routing domain,  ~.
  4. 其实看到这里我已经大概明白了我应该怎么做,只是除了不完美,比如如果我直接修改/etc/resolve.conf设置我的routing domain为VPN的tun0为~.应该就是可以的,只不过我想能不能使用D-Bus的API来作,否则每次都要修改文件是很烦人。因为我的VPN不是自动开机启动的。 这里回答了开机脚本调用参数修改dns设置的方式。但是问题是我的openvpn的DNS我访问不了,它是亚马逊的云服务器,这个是不是有了更复杂的一层呢?
  5. 我读了这么多,但是我始终不确定要怎么做,甚至于我还是不敢肯定到底我的问题是不是能够解决。我决定不管如何尝试一下:
    
    nick@nick-sager:~$ resolvectl domain tun0 '~.'
    nick@nick-sager:~$ resolvectl default-route tun0 true
    nick@nick-sager:~$ resolvectl dns tun0 8.8.8.8
    
    然后这个是结果
    
    nick@nick-sager:~$ resolvectl status
    Global
           Protocols: -LLMNR -mDNS DNSOverTLS=opportunistic DNSSEC=no/unsupported
    resolv.conf mode: stub
    
    Link 2 (enp0s31f6)
        Current Scopes: DNS
             Protocols: +DefaultRoute +LLMNR -mDNS DNSOverTLS=opportunistic DNSSEC=no/unsupported
    Current DNS Server: fe80::1
           DNS Servers: 8.8.8.8 218.85.152.99 218.85.157.99 fe80::1%21970
    
    Link 3 (wlp109s0)
    Current Scopes: none
         Protocols: -DefaultRoute +LLMNR -mDNS DNSOverTLS=opportunistic DNSSEC=no/unsupported
    
    Link 11 (tun0)
    Current Scopes: DNS
         Protocols: +DefaultRoute +LLMNR -mDNS DNSOverTLS=opportunistic DNSSEC=no/unsupported
       DNS Servers: 8.8.8.8
        DNS Domain: ~.
    
    但是我依旧无法在命令行ping到谷歌和脸书,但是我现在chromium可以正常访问谷歌了,这个难道不是结果吗?然后我发现ping只能支持ipv4,就是说
    ping -4 www.google.com
    是可以的。 也许我可以自己加个脚本在openvpn启动的时候执行上述的命令,这样子就不是直接修改conf文件那么麻烦了。但是我确实是禁止了ipv6为什么不起作用呢?看来问题还是很复杂的。 但是不管怎样我至少解决我的困扰的huggingface-cli必须要设立镜像才能访问的问题。
    
    nick@nick-sager:~$ unset HF_ENDPOINT
    nick@nick-sager:~$ huggingface-cli download gpt2 config.json
    Consider using `hf_transfer` for faster downloads. This solution comes with some limitations. See https://huggingface.co/docs/huggingface_hub/hf_transfer for more details.
    /home/nick/.cache/huggingface/hub/models--gpt2/snapshots/11c5a3d5811f50298f278a704980280950aedb10/config.json
    nick@nick-sager:~$ 
    
    不过目前这些成果我还没有形成可靠的机制,如果重启电脑可能又要重新设置。我想还是要验证一下再说。不管怎么样还是有一点点的成就感的。让我比较一下我的openvpn上的解析和本地是否一样:
    
    openvpnas@ip-172-31-35-59:~$ resolvectl query www.google.com
    www.google.com: 142.250.189.164                -- link: eth0
                    2607:f8b0:4005:80e::2004       -- link: eth0
    
    而我的本地
    
    nick@nick-sager:~$ resolvectl query www.google.com
    www.google.com: 172.217.164.100                -- link: tun0
                    2607:f8b0:4005:80c::2004       -- link: tun0
    
    这个说明了什么呢?难道是我的概念从一开始就是错误的,根本不是DNS解析的问题?那么为什么现在可以工作了呢? 那么我们看看两者的route路径如何吧? 这个是本地的,注意的确是走到了VPN的IP172.27.232.1,单单是这一点就足够了吧。因为从后面的路径分岔是应该是在当地找最快的路径每次都不同而已?
    
    nick@nick-sager:~$ traceroute www.google.com
    traceroute to www.google.com (172.217.164.100), 30 hops max, 60 byte packets
     1  172.27.232.1 (172.27.232.1)  163.430 ms  164.283 ms  164.225 ms
     2  244.5.0.17 (244.5.0.17)  166.724 ms 244.5.0.151 (244.5.0.151)  164.419 ms 244.5.0.17 (244.5.0.17)  166.733 ms
     3  240.0.180.36 (240.0.180.36)  164.240 ms 100.65.17.96 (100.65.17.96)  175.723 ms 100.65.16.128 (100.65.16.128)  188.759 ms
     4  240.0.168.12 (240.0.168.12)  164.946 ms 100.66.8.226 (100.66.8.226)  184.148 ms 100.66.8.0 (100.66.8.0)  338.800 ms
     5  100.66.10.66 (100.66.10.66)  178.329 ms * *
     6  241.0.6.199 (241.0.6.199)  164.177 ms 72.14.197.18 (72.14.197.18)  164.947 ms 241.0.6.207 (241.0.6.207)  164.339 ms
     7  240.0.168.13 (240.0.168.13)  164.994 ms 240.0.168.15 (240.0.168.15)  165.019 ms  165.015 ms
     8  142.251.66.108 (142.251.66.108)  167.275 ms * 142.251.224.172 (142.251.224.172)  165.467 ms
     9  192.178.105.118 (192.178.105.118)  166.057 ms 209.85.252.251 (209.85.252.251)  166.081 ms  166.159 ms
    10  sfo03s18-in-f4.1e100.net (172.217.164.100)  165.434 ms 192.178.105.113 (192.178.105.113)  165.433 ms sfo03s18-in-f4.1e100.net (172.217.164.100)  164.973 ms
    
    而openvpn上呢?
    
    openvpnas@ip-172-31-35-59:~$ traceroute www.google.com
    traceroute to www.google.com (142.251.32.36), 30 hops max, 60 byte packets
     1  244.5.0.147 (244.5.0.147)  4.191 ms 216.182.237.205 (216.182.237.205)  7.062 ms 216.182.237.199 (216.182.237.199)  7.470 ms
     2  * 100.65.17.128 (100.65.17.128)  12.839 ms 100.65.19.160 (100.65.19.160)  21.472 ms
     3  240.0.168.12 (240.0.168.12)  0.996 ms 100.66.8.160 (100.66.8.160)  12.075 ms 100.66.8.148 (100.66.8.148)  18.355 ms
     4  * 100.66.10.130 (100.66.10.130)  13.099 ms 100.66.10.234 (100.66.10.234)  22.329 ms
     5  72.14.203.108 (72.14.203.108)  2.291 ms 241.0.6.199 (241.0.6.199)  0.300 ms 241.0.6.195 (241.0.6.195)  0.317 ms
     6  * 240.0.168.15 (240.0.168.15)  1.009 ms *
     7  142.251.228.80 (142.251.228.80)  1.485 ms 142.251.241.102 (142.251.241.102)  1.488 ms 142.251.224.172 (142.251.224.172)  1.502 ms
     8  192.178.105.98 (192.178.105.98)  1.464 ms 192.178.105.106 (192.178.105.106)  1.478 ms 142.251.224.179 (142.251.224.179)  1.440 ms
     9  * 192.178.105.95 (192.178.105.95)  1.562 ms sfo03s26-in-f4.1e100.net (142.251.32.36)  1.364 ms
    
    而最后两者殊涂同归到达域名sfo03s26-in-f4.1e100.net是最重要的,至于说具体IP不同那个是IP routing的问题吧?至于说为什么IPV6不工作,我想这个也许是别的设置的问题?我在openvpn上发现它似乎有ipv6的问题吧?
    
    openvpnas@ip-172-31-35-59:~$ traceroute -6 www.google.com
    traceroute to www.google.com (2607:f8b0:4005:812::2004), 30 hops max, 80 byte packets
    connect: Network is unreachable
    
  6. 也许我今天可以好好的休息一下,似乎困扰我的网络问题终于有了一个解决方案。
  7. 顺便说一下,获得FQDN是可以通过hostname -f

二月十六日 等待变化等待机会

  1. 在解决了一个大问题回到Stable-Diffusion之前通常应该休整一段时间,但是我觉得没必要。在选择深入了解openClip和继续概览stable-diffusion全貌之间我选择后者。
  2. 这个embedding是每一个token都独自拥有的。
    Stable diffusion v1 uses Open AI’s ViT-L/14 Clip model. Embedding is a 768-value vector. Each token has its own unique embedding vector. Embedding is fixed by the CLIP model, which is learned during training.
    对于SDv1这个古老的遗迹我觉得有必要熟悉起来。不了解历史是无法深刻领会现实的。
    Note: Stable Diffusion v1 is a general text-to-image diffusion model and therefore mirrors biases and (mis-)conceptions that are present in its training data. Details on the training procedure and data, as well as the intended use of the model can be found in the corresponding model card.
    保存一份相当不错的论文。我的理解就是团队发现语言模型的完善可以自动完善text-image的训练过程,难道语言和图像有着某种内在的联系?人们说一幅画包含了千言万语,这个不是没有道理的:

    远看山有色,近听水无声。 春去花还在,人来鸟不惊。
    对于每个token都有768-value的vector相联系,我以为虽然是上下文的标识,但也就是默认了文字和图像一样是高维的物件,那么它们在高维度上的契合也就是自然而然的,更何况人们判定文字和图像契合的点乘本身就是要求两者在纬度上的一致。
    We discover that large frozen language models trained only on text data are surprisingly very effective text encoders for text-to-image generation, and that scaling the size of frozen text encoder improves sample quality significantly more than scaling the size of image diffusion model.
    这篇论文的核心贡献!这里有一个排行榜,看来挺有用的,可以了解趋势。

二月十七日 等待变化等待机会

  1. 阅读这篇论文
    1. 传统的text-image模型通常是比较小的,因为这个数据的采集以及准确性的保证都是一个难题。结果另辟蹊径是提高语言模型的尺寸相对容易,毕竟不是一个维度的东西。但是没想到结果却是有效的提高了对于text-image模型的准确识别率,这个是一个无心插柳柳成荫的结果。
    2. It thus becomes natural to explore both families of text encoders for the text-to-image task. Imagen explores pretrained text encoders: BERT, T5 and CLIP. For simplicity, we freeze the weights of these text encoders. Freezing has several advantages such as offline computation of embeddings, resulting in negligible computation or memory footprint during training of the text- to-image model.
      看起来我也应该学习使用现成的text-encoder,比如openClip就应该成为下一个目标任务。就是说我也可以在我的简陋条件下来训练?
    3. 什么是diffusion model呢?
      Diffusion models are a class of generative models that convert Gaussian noise into samples from a learned data distribution via an iterative denoising process. These models can be conditional, for example on class labels, text, or low-resolution images.
      补习数学:什么是Gaussian noise
      In signal processing theory, Gaussian noise, named after Carl Friedrich Gauss, is a kind of signal noise that has a probability density function (pdf) equal to that of the normal distribution (which is also known as the Gaussian distribution). In other words, the values that the noise can take are Gaussian-distributed.
      为什么是Gaussian noise,其实要理解它的来源。如果它是我们很普通的电子设备和传感器天然得到的,那么人脑也应该有类似的机制产生,那么。。。
      Principal sources of Gaussian noise in digital images arise during acquisition e.g. sensor noise caused by poor illumination and/or high temperature, and/or transmission e.g. electronic circuit noise.
      所以,降噪是一个还原图像的逆过程?难道说熵减少?充满了噪音的信号显然是宇宙中最普遍的现象,而人脑是训练可以降噪的,人类的神经系统肯定不可能如我们的硅基电子设备来的精密,所以,人类的大脑天天都在和信号传输过程的噪音做斗争,因此,这个是人脑的天然的过程。那么降噪的方法呢?
      In digital image processing Gaussian noise can be reduced using a spatial filter, though when smoothing an image, an undesirable outcome may result in the blurring of fine-scaled image edges and details because they also correspond to blocked high frequencies. Conventional spatial filtering techniques for noise removal include: mean (convolution) filtering, median filtering and Gaussian smoothing.
    4. 让我们首先来理解什么是Spatial filter
      A spatial filter is an optical device which uses the principles of Fourier optics to alter the structure of a beam of light or other electromagnetic radiation, typically coherent laser light. Spatial filtering is commonly used to "clean up" the output of lasers, removing aberrations in the beam due to imperfect, dirty, or damaged optics, or due to variations in the laser gain medium itself.
      那么又要首先明白什么是Fourier optics
      Fourier optics is the study of classical optics using Fourier transforms (FTs), in which the waveform being considered is regarded as made up of a combination, or superposition, of plane waves. It has some parallels to the Huygens–Fresnel principle, in which the wavefront is regarded as being made up of a combination of spherical wavefronts (also called phasefronts) whose sum is the wavefront being studied. A key difference is that Fourier optics considers the plane waves to be natural modes of the propagation medium, as opposed to Huygens–Fresnel, where the spherical waves originate in the physical medium.
      这一段相当的深奥,结果维基百科很贴心的没有中文版本!TMD连越南语版本都有为什么没有中文版!难道中文里没有傅里叶光学?这里深奥的就是传播介质还是物理介质,波是能量自然会引起介质的运动,电磁波难道不是像微波炉一样的给介质加热传播能量吗?其核心的研究方法是傅里叶变换,这个难道是数字化作为研究的数学手段?总之它是一门科学。我需要的是具体的手段,而不是理论。
    5. 这里有一个很重要的概念是coherent laser light,我刚刚才意识到这个干扰是天生的,从同一个光源发出的固定频率光束天生就是干扰的来源:
      In physics, coherence expresses the potential for two waves to interfere. Two monochromatic beams from a single source always interfere. Physical sources are not strictly monochromatic: they may be partly coherent. Beams from different sources are mutually incoherent.
      就是说这个干扰原是天生的!不过我对于这句话就不大理解了:Beams from different sources are mutually incoherent.但是话说回来了,我需要了解或者理解这些信号领域的深奥概念吗?这是一个人穷尽一生都未必能够精通的概念领域。我需要的是理解为什么而不是怎么做。
    6. 我还是回到降噪的三种途径吧:
      Conventional spatial filtering techniques for noise removal include: mean (convolution) filtering, median filtering and Gaussian smoothing.
    7. 这些都很难懂,至少我觉得convolution比较难吧,你能写出真的函数来吗?
    8. 而相比之下median filter就很好理解了,就是去角化,把过于突出的极化部分拉平使得圆滑。
      The main idea of the median filter is to run through the signal entry by entry, replacing each entry with the median of neighboring entries.
      我觉得这个思路就是利用了正态分布的噪音特点,凡是超出周边范畴的就去除?也许不准确,不过算法是比较好理解的,有点interpolition的反向操作?
    9. 第三种Gaussian blur才是有技术含量的高大上:
      In image processing, a Gaussian blur (also known as Gaussian smoothing) is the result of blurring an image by a Gaussian function (named after mathematician and scientist Carl Friedrich Gauss).
      这个要怎么理解呢?能不能理解它是一种特殊的convolution呢?
    10. 吃了早饭我想这些都是作为下一步理解denoise的工具的储备知识。有个概念就好。另一个比较难以理解的是如何把64x64的基础图片扩展成256x256以及1024x1024而不失真?
      magen uses noise conditioning augmentation for both the super-resolution models. We find this to be a critical for generating high fidelity images.
      什么是noise conditioning augmentation
      Given a conditioning low-resolution image and augmentation level (a.k.a aug_level) (e.g., strength of Gaussian noise or blur), we corrupt the low-resolution image with the augmentation (corresponding to aug_level), and condition the diffusion model on aug_level. During training, aug_level is chosen randomly, while during inference, we sweep over its different values to find the best sample quality. In our case, we use Gaussian noise as a form of augmentation, and apply variance preserving Gaussian noise augmentation resembling the forward process used in diffusion model.
      这里能不能理解就是augmentation level=strength of Gaussian noise or blur?训练的时候是遍历所有的可能,也就是用随机数,而推理的时候则是反向的使用所有的可能性来找到最佳值。什么是diffusion model的forward process?看来我要重温一下基本的概念。
    11. 如何验证是非常重要的学习领域。这里提到使用COCO,我已经下载了。什么是FID呢?为什么CLIP score可以做检验?它是什么?
      Both FID and CLIP scores have limitations, for example FID is not fully aligned with perceptual quality, and CLIP is ineffective at counting.
      作者指出的这些缺陷是什么意思?这里人为鉴定的方法很有趣:
      1. To probe image quality, the rater is asked to select between the model generation and reference image using the question: “Which image is more photorealistic (looks more real)?”. We report the percentage of times raters choose model generations over reference images (the preference rate).
      2. To probe alignment, human raters are shown an image and a prompt and asked “Does the caption accurately describe the above image?”. They must respond with “yes”, “somewhat”, or “no”. These responses are scored as 100, 50, and 0, respectively. These ratings are obtained independently for model samples and reference images, and both are reported.
      第一个回答可信度也就是质量问题。第二个是准确度,这个很好理解,但是似乎作者对于COCO数据库原来的标题也不是很信赖,否则为什么要独立的验证它?难道我理解错了?也许原本的训练库就不够贴合。注意,作者的模型是没有在COCO上训练过的,这一点很重要,不像很多是在训练库里训练出的模型再回炉去那么它能证明什么?记忆力吗?我甚至怀疑这么大量的相类似的库难免有重叠,或者说相类似吧?这个是逃不掉的。人类总是类似的吧?这样子的训练就不是什么开创性的了,而是比赛记忆力了。而作者的训练是一个纯粹的语言模型,只不过它借用了之前别人训练好的模型提高了质量,这里有着非常微妙的差别?
    12. 这里要学习一个概念Zero-shot learning
      Zero-shot learning (ZSL) is a problem setup in deep learning where, at test time, a learner observes samples from classes which were not observed during training, and needs to predict the class that they belong to.
      这个和我直觉是一样的,当然是要训练时候没有见过才行,否则就是考验记忆力了。这和人类学习中的举一反三有异曲同工之效。不过比我想象的要难的多,就是
      For example, given a set of images of animals to be classified, along with auxiliary textual descriptions of what animals look like, an artificial intelligence model which has been trained to recognize horses, but has never been given a zebra, can still recognize a zebra when it also knows that zebras look like striped horses.
      这里的反三不是简单的类比而是要上一个层次,是真正的要理解语言的描述,而不是平行类比。
    13. 我觉得这个截图是高度概括了这篇论文: 虽然是借鸡生蛋,但是很有独创性,而且我对于它的drawbench很感兴趣。这个是有人对于它的比较。这些prompt是特意挑选的吗?这个描述是自行车:
      A vehicle composed of two wheels held in a frame one behind the other, propelled by pedals and steered with handlebars attached to the front wheel.
      我觉得很多人类都未必能理解。
    14. 似乎我应该看看Imagen因为感觉DrawBench也许只是一个小工具?编译有问题,然后我就借用我的SD的虚拟环境:
      
      source ../stable-diffusion-webui/venv/bin/activate
      python setup.py install
      
    15. 什么是DDPM(Denoising Diffusion Probabilistic Model)?它和GAN有什么关系? 这个似乎才是官方的库?
      Generative adversarial networks (GANs) are an exciting recent innovation in machine learning. GANs are generative models: they create new data instances that resemble your training data.
      没什么关系,但是为什么当初这个东西和generative content有关系呢?在我看来这个是相当传统的人工智能的模式。
      A generative adversarial network (GAN) is a class of machine learning frameworks and a prominent framework for approaching generative AI. The concept was initially developed by Ian Goodfellow and his colleagues in June 2014. In a GAN, two neural networks contest with each other in the form of a zero-sum game, where one agent's gain is another agent's loss.
      这个训练方式是很有意思的,就是双方是博弈关系,你的训练对手给你的是错误的指引?
      The core idea of a GAN is based on the "indirect" training through the discriminator, another neural network that can tell how "realistic" the input seems, which itself is also being updated dynamically. This means that the generator is not trained to minimize the distance to a specific image, but rather to fool the discriminator. This enables the model to learn in an unsupervised manner.
      这样子岂不是越跑越偏吗?这个结果还能看吗?
  2. 完全偏离了方向,踏入了不可自拔的泥潭,因为我没有这方面的基础知识尤其是数学基础,这个领域非常的困难,而且我也缺乏基本的python的基础让这些实验更加的困难。我似乎应该回到高概括性的浏览熟悉层级上来。准备回到这个通览节点
  3. 我想把我的微信聊天记录备份到电脑,但是weixin.qq.com不提供Linux版本,于是我就是下载windows版本使用本地的wine的loader来运行安装,结果高级功能会crash,不过备份还是可以做得到的。

二月十八日 等待变化等待机会

  1. 不要指望学习无上的内功心法,那个需要极高的数学基础和大量的AI的技术储备知识,对于连基本的论文都看不懂的门外汉来说是水中捞月。但是如果仅仅是学习武功的招式,运用法门,那么哪怕是一个零基础的门外汉也不是什么大问题,只要下一些功夫,因为武功心法是给内功修炼者看的,但是练功口诀却是给普通练习者学习用的。
  2. 这个就是你需要了解的细节,对于普通使用者似乎没有必要了解各个环节,但是正如修车和开车的关系一样,普通驾驶者满足于正常驾驶,这个在普通道路上可能都没有问题,但是对于崎岖山路,又或是一部二手老爷车,经常在道路上维修也许就需要了解基本的机械结构,实施普通的维修保养,尤其是车子本身就是拼凑出的多方零件来源的话。
    The embedding needs to be further processed by the text transformer before feeding into the noise predictor. The transformer is like a universal adapter for conditioning.
    这里点出了conditioning要在什么节点发力。而embedding如何成为latent space的向量恐怕不是那么简单的。这里就是语言模型的关键,否则单单靠词频上下文产生的tokenizer不可能有这么强大吧?
  3. In this case, its input is text embedding vectors, but it could as well be something else like class labels, images, and depth maps. The transformer not only further processes the data but also provides a mechanism to include different conditioning modalities.
    这里点出了一个关键点,text-prompt最后是映射到了什么?它是等同于image-text-pair里的caption部分?显然不是,但是分类是这些caption的一部分功能,所以,如果简简单单就是class label也许是一个shortcut,但是我不清楚它和内部的embedding是什么关系,也许class-label仅仅是一个比较特殊的text-prompt,正像很多人口中的咒语一样,但是这一点看起来也很像是conditioning,也许两者本来就是一样的东西。只是实际使用起来我感觉这些keywords的位置似乎没有关系,这个在向量生成里说不通了。也许我的观察是不对的,但是它的特殊性是一定的。很prompt专门加各种挂号引号,仅仅是为了强调这个要单独tokenize吗?还是要作为class-label?这个是今后要回答的问题。另一方面,img2img的机制显然和text2img的不一样,但是似乎它们使用了同样的模型,这里难道说text-prompt最后的embedding转化结果就是image的latent space vector?这个也是需要进一步理解的。到时候水到渠成,瓜熟蒂落。这里的插曲是depth image。作者专门有一篇教程来利用它做一些高难度的动作,这个似乎看上去像是controlNet异曲同工之效,所有的text-prompt都是某种conditioning,问题是如何才是最有效的,动作指引edge detection以及其他做法从直觉上看是给text-image过程一个类似模板的东西,就是说在Gaussian noise下原始的信号是什么?你给的越是贴近目标那么降噪的偏差就越小,这个是不言而喻的。原理人人都明白,但是魔鬼都在细节。 Knowing the path is totally diffferent from actually walking the path.很多人不屑于具体的操作法门,认为那是不重要的实作,然而练拳不练功,到头一场空,作为战场格斗的士兵的基本职能并不是你自己以为的武林宗师一样要你在观众席上作不负责任的指指点点。
  4. 作者要用这个浪漫场景来生成两个男人摔跤的图片,我想实践看看效果如何。
    treat depth-to-image as an enhanced version of image-to-image. They can be used in exactly the same way — given an image and a text prompt, it will generate a new image.
    用普通的img2img产生的就是和图片人体形体基本无关的摔跤场景。那么depth-to-image在哪里呢?不过这里让我亲身感到如果denoise调的较小的话,那么产生的图片就和原来的基本一致,仿佛就是这个量是一个变形参数一样。
  5. 这里才是关键的怎么做之前的是什么
    In depth-to-image, Stable Diffusion similarly takes an image and a prompt as inputs. The model first estimates the depth map of the input image using MIDaS, an AI model developed in 2019 for estimating monocular depth perception (that is estimating depth from a single view). The depth map is then used by Stable Diffusion as an extra conditioning to image generation.
    一言以蔽之:an extra conditioning
    In other words, depth-to-image uses three conditionings to generate a new image:
    1. text prompt
    2. original image
    3. depth map
    但是这里的foreground-object和background是什么呢?
    Equipped with the depth map, the model has some knowledge of the three-dimensional composition of the scene. Image generations of foreground objects and the background can be separated.
  6. 作者似乎是使用这个网站来生成depth-image。
  7. 在国内就是时时刻刻被网络所困扰,我发现我昨天以为成功的设置又都失效了,似乎tun0这个自己更新了?总之,resolvectl status可以看到原来的设置消失了。我又要重复一下,以后看能不能用脚本运行,不过这些需要sudo权利,是否在D-Bus那里可以使用user权利?
  8. 回到问题,设置midas。我下载了它的模型以及配置文件,按照作者的步骤重复了一遍,从摔跤的动作来看的确是保全了原来图像的形态,但是人物形象让人惨不忍睹,这个和模型的质量有关吧?或许没有添加相关的negative prompt?总之,并不是令人满意。作者又说了一些应用场景,比如换脸的时候如果要保持原图的形态,那么denoise就不能很大,结果不会太好。使用depth-image模型就可以自由调整denoise参数任意变化。不过我感觉效果也不像作者的结果那么理想,也许还有别的参数作者没有提到?或者我的模型配置问题?总之,这个是一个有意义的尝试。
  9. 顺便说一下,如果使用国内的DNS解析raw.githubusercontent.com,结果可能就是0.0.0.0,这个也许是DNS的cache也许是人为设置障碍,总之这个是正确的解析:
    
    $ nslookup raw.githubusercontent.com
    Server:		127.0.0.53
    Address:	127.0.0.53#53
    
    Non-authoritative answer:
    Name:	raw.githubusercontent.com
    Address: 185.199.111.133
    Name:	raw.githubusercontent.com
    Address: 185.199.109.133
    Name:	raw.githubusercontent.com
    Address: 185.199.110.133
    Name:	raw.githubusercontent.com
    Address: 185.199.108.133
    Name:	raw.githubusercontent.com
    Address: 2606:50c0:8000::154
    Name:	raw.githubusercontent.com
    Address: 2606:50c0:8001::154
    Name:	raw.githubusercontent.com
    Address: 2606:50c0:8002::154
    Name:	raw.githubusercontent.com
    Address: 2606:50c0:8003::154
    
  10. 这些当然都是很好的应用场景。不过我对于这个模型的质量还是将信将疑。比如我可以使用img2txt的方式先获得相当准确的prompt,例如对于La La Land我使用Interrogate DeepBooru获得的相当详细的prompt:
    
    1boy, 1girl, brown hair, city, city lights, dancing, dress, facial hair, fireworks, high heels, necktie, night, outdoors, outstretched arm, outstretched arms, outstretched hand, pants, road, shoes, short hair, sky, spread arms, street, tree, water, yellow dress
    
    然后再txt2img得到的结果也不算很差劲儿 应该说卡通化可以掩盖大部分的缺陷,这个也许是目前的一个解决办法。
  11. 按照从易到难的程度,text,audio,video,所以,我想看看这个whisper项目,这个也是OpenAI的开源项目吧?有开源吗?
    
    git clone --recursive https://github.com/openai/whisper
    cd whisper
    pip install .	
    whisper --model "medium" --output_format srt --verbose True --task transcribe --language Mandarin --output_dir ./output output.mp3
    ffmpeg -i input.mp4 -vf subtitles=./output/output.srt ./output.mp4
    
    效果只能说还可以,因为有些专有名字我们人类可以很容易识别,但是模型不行,此外,有些我也听不出的部分机器就乱翻了。
  12. 这个cross attention我反复看到过,但是不理解它的意义:
    The output of the text transformer is used multiple times by the noise predictor throughout the U-Net. The U-Net consumes it by a cross-attention mechanism. That’s where the prompt meets the image.
    它是在U-Net里?被noise predictor使用的机制?
    A side note: Hypernetwork, a technique to fine-tune Stable Diffusion models, hijacks the cross-attention network to insert styles. LoRA models modify the weights of the cross-attention module to change styles. The fact that modifying this module alone can fine-tune a Stabe Diffusion model tells you how important this module is.
    这就意味着我需要了解LoRA
    LoRA (Low-Rank Adaptation) is a training technique for fine-tuning Stable Diffusion models.
    也就是说训练模型是费时费力的,修改模型也是费时费力,更加麻烦的是模型文件的大小经常是好几个G,那么TI比较小,但是功能有限,而LoRA大小只有几百兆比较适中。
    LoRA applies small changes to the most critical part of Stable Diffusion models: The cross-attention layers. It is the part of the model where the image and the prompt meet.
  13. 这幅图描述了整个流程: 这幅图是从这篇stable diffusion paper里来的。再看看论文作者的关于latent space的描述:
    Compared to the high-dimensional pixel space, this space is more suitable for likelihood-based generative models, as they can now
    1. focus on the important, semantic bits of the data and
    2. train in a lower dimensional, computationally much more efficient space.
    这是diffusion model的数学描述:
    Diffusion Models are probabilistic models designed to learn a data distribution p(x) by gradually denoising a nor- mally distributed variable, which corresponds to learning the reverse process of a fixed Markov Chain of length T . For image synthesis, the most successful models rely on a reweighted variant of the variational lower bound on p(x), which mirrors denoising score-matching. These models can be interpreted as an equally weighted sequence of denoising autoencoders εΘ (xt , t); t = 1 . . . T , which are trained to predict a denoised variant of their input xt , where xt is a noisy version of the input x. The corre- sponding objective can be simplified to L DM = E x,ε∼N (0,1),t [ ||ε - ε Θ ( x t ,t) || 2 2 ]
    我费了好大的力气去写这个公式,其实根本就不理解数学符号的意义,但是从描述大概能够猜出来可能的大概意思。就是说。。。
  14. 这里是关于LoRA的论文,而关于它的诀窍就是
    The weights of a cross-attention layer are arranged in matrices. A LoRA model fine-tunes a model by adding its weights to these matrices. The trick of LoRA is breaking a matrix into two smaller (low-rank) matrices.
    因为LoRA就是weight matrix。而我现在的直觉就是计算机里最普通的关于压缩的小技巧,针对matrix里大量的0,完全可以舍弃掉而只储存那些有数值的部分。这个是任何一个人都能想得到的方法。
    ...the learned over-parametrized models in fact reside on a low intrinsic dimension. We hypothesize that the change in weights during model adaptation also has a low “intrinsic rank”...LoRA allows us to train some dense layers in a neural network indirectly by optimizing rank decomposition matrices of the dense layers’ change during adaptation instead, while keeping the pre-trained weights froze
    这里有LoRA的源代码,在其说明文字里解释的就更清楚了,它不是shipment的节约,因为你还是需要原始的模型,但是训练的时候你节约了,因为有很多的参数不需要训练。那么我认为运行期模型需要的资源也相对减少了。所以,你可以在原来模型基础上训练自己的模型,而且更省力。这个专业的说法叫做fine-tuning。 这里是LoRA的优点
    • A pre-trained model can be shared and used to build many small LoRA modules for dif- ferent tasks. We can freeze the shared model and efficiently switch tasks by replacing the matrices A and B in Figure 1, reducing the storage requirement and task-switching over- head significantly.
    • LoRA makes training more efficient and lowers the hardware barrier to entry by up to 3 times when using adaptive optimizers since we do not need to calculate the gradients or maintain the optimizer states for most parameters. Instead, we only optimize the injected, much smaller low-rank matrices.
    • Our simple linear design allows us to merge the trainable matrices with the frozen weights when deployed, introducing no inference latency compared to a fully fine-tuned model, by construction.
    • LoRA is orthogonal to many prior methods and can be combined with many of them, such as prefix-tuning.
    简而言之,训练效率提高,部署有优势(假定通用模型已经部署,只是分发fine-tuned的LoRA模型),运用时候没有额外成本,方法独立可以和其他方法并用。就是说它是训练方便,使用没有区别。
  15. 补习一下基本概念:
    An autoregressive language model is a type of Machine Learning model that uses autoregressive techniques to predict the next word in a sequence of words based on the words that have come before it.
    可以说现在通常所说的模型都是AutoRegressive language model。
  16. 我的幼稚在于只能理解都是0的matrix部分,就是linearly dependent的部分,而真正的可以忽略的还包含了那些非独立的向量部分
    In linear algebra, the rank of a matrix A is the dimension of the vector space generated (or spanned) by its columns. This corresponds to the maximal number of linearly independent columns of A.
    这么看起来矩阵其实可以分别计算它的行与列的rank,而最大值代表了矩阵的rank。A fundamental result in linear algebra is that the column rank and the row rank are always equal.
    The column rank of A is the dimension of the column space of A, while the row rank of A is the dimension of the row space of A.
    而这个matrix的rank只有2,因为column1和column2的线性组合是column3。 [ 1 0 1 0 1 1 0 1 1 ]
  17. 这里是html里的math部分,很多复杂公式需要用到它。
  18. 这里的解释我就立刻明白为什么decomposition rank等同于matrix factorization了。

    Decomposition rank

    The rank of A is the smallest integer k such that A can be factored as A = C R, where C is an m × k matrix and R is a k × n matrix. In fact, for all integers k, the following are equivalent:
    1. the column rank of A is less than or equal to k,
    2. there exist k columns c1 , … , ck of size m such that every column of A is a linear combination of c1 , … , ck,
    3. there exist an m × k matrix C and a k × n matrix R such that A = C R (when k is the rank, this is a rank factorization of A),
    4. there exist k rows r1 , … , rk of size n such that every row of A is a linear combination of r1 , … , rk,
    5. the row rank of A is less than or equal to k.
    Indeed, the following equivalences are obvious: ( 1 ) ⇔ ( 2 ) ⇔ ( 3 ) ⇔ ( 4 ) ⇔ ( 5 ) . For example, to prove (3) from (2), take C to be the matrix whose columns are c1 , … , ck from (2). To prove (2) from (3), take c1 , … , ck to be the columns of C.
    从这就可以看出来我之前的直觉也没有错,如果部分的matrix是0,那当然可以舍弃,其实这个是从化简后的row/column echelon form的角度来看问题,直觉能看到0却没有看到线性相关,当然线性相关意味着可以被化简为0。所以,最深奥的理论往往来自于最肤浅的直觉。
  19. 从一篇好的论文能够牵扯到一堆的好的论文,这就是好的论文的意义。花花轿子人抬人。这篇论文据说有谈到GPT的架构。
    In this work we propose the Transformer, a model architecture eschewing recurrence and instead relying entirely on an attention mechanism to draw global dependencies between input and output. The Transformer allows for significantly more parallelization and can reach a new state of the art in translation quality after being trained for as little as twelve hours on eight P100 GPUs.
    要明白这里的关键就是attention。而要明白作者提出的cross attention首先要明白原先的Self-attention
    Self-attention, sometimes called intra-attention is an attention mechanism relating different positions of a single sequence in order to compute a representation of the sequence. Self-attention has been used successfully in a variety of tasks including reading comprehension, abstractive summarization, textual entailment and learning task-independent sentence representations.
  20. 这里既要补习英语也要补习概念
    Transduction (machine learning), the process of directly drawing conclusions about new data from previous data, without constructing a model
    而这一段解释非常的深奥:
    In logic, statistical inference, and supervised learning, transduction or transductive inference is reasoning from observed, specific (training) cases to specific (test) cases. In contrast, induction is reasoning from observed training cases to general rules, which are then applied to the test cases. The distinction is most interesting in cases where the predictions of the transductive model are not achievable by any inductive model. Note that this is caused by transductive inference on different test sets producing mutually inconsistent predictions.
    这些概念的语言版本有莫名其妙的少数族裔语言,比如亚美尼亚,波斯,俄语,可是居然没有汉语! 就是说要解决逻辑推理苏格拉底是人类需要从具体到一般的归纳总结能力吗?
    induction requires solving a more general problem (inferring a function) before solving a more specific problem. When solving a problem of interest, do not solve a more general problem as an intermediate step. Try to get the answer that you really need but not a more general one.
    这的确是一个很深奥的问题,这个quora回答的大致和wiki相似,不过更加的形象生动一些。 这个抽象的概括总结一开始把人吓死了:

    Inductive learning is nothing but the principle behind the supervised machine learning algorithms where a model tries to build a relationship between the feature variables and target variable by examining the hidden patterns in the train data. Although the model is exposed to a restricted scope of the training data, the learning of the model will be according to a generic nature of data such that it can predict the value of any data point from an unlabelled dataset (test dataset). This kind of learning is termed inductive learning. It is to be noted here that the model is not exposed to the test data during the learning phase and is only provided with the training data for the learning purpose.p

    In transductive learning, both training and testing data set is exposed to the model in the learning phase itself. The model tries to find any information about the pattern in the combined dataset (training + testing) and later uses this information for predicting the values of the unlabelled testing data points.

    其实如果这么解释就好懂的多了,inductive是一种严格的supervised learning模式,它有着优越的地方在于它的学习数据被严格筛选过,就是说学习数据都有标记;而与之相对应的transductive则没有那种奢侈可以事先把学习数据严格标记,只有部分标记,也不存在inductive那样可以用同样严格筛选过的实验数据来检验。粗略的看就是transductive就是时间紧任务重来不及准备充分就让你去边学边练。
    • Inductive learning trains the model with labeled data points and tries to predict the label of unlabeled data points. However, transductive learning trains the entire data set and tries to predict the label of unlabeled data points.
    • In inductive learning, if a new unlabelled data point is getting introduced then we can use the already trained model for the prediction. However, in transductive learning, we may need to retrain the entire model.
    • Transductive learning is computationally expensive than inductive learning.
  21. 我今天也不学了,机器学习,我也学习。累死了。

二月十九日 等待变化等待机会

  1. 我以为革命发生在Departure to Latent Space。不要仅仅以为它是某种压缩技术的革命,量变引起的质变往往在它发生的时候被大多数人所忽视。因为它从内在触及了图形识别的本质,图形本身的意义部分(semantic),和图形可识别部分(perceptual)是两个物件,而压缩的本质就是最大限度保留semantics而忽略所谓的imperceptual的部分。这篇stable-diffusion-paper读多少遍都不为过,它太重要了。

    Departure to Latent Space

    Our approach starts with the analysis of already trained diffusion models in pixel space.
    这里说的是作者出发地。几乎所有的革命性发现发明都是建立在前人的成果基础上的,所以,站在巨人的肩膀上。
    As with any likelihood-based model, learning can be roughly divided into two stages: First is a perceptual compression stage which removes high-frequency details but still learns little semantic variation. In the second stage, the actual generative model learns the semantic and conceptual composition of the data (semantic compression).
    1. 这个是极其精炼的总结,短短的文字蕴藏了几乎无限的信息。首先定义对象是likelihood-based model,这个背后的含义就是巨大的,其实最基本的概念的建立有时候花的时间是超出想象的长,现在这些模型的本质是什么?或者说它里面究竟存了些什么呢?我没有看过,没有感性认识。我没有具体实践过。但是提纲挈领的断言它是一个概率模型就是一锤定音的。
    2. 第一阶段在做什么?perceptual compression的具体含义是什么?什么又是perceptual的内容呢?或者说什么是high-frequency details?怎么界定频率?怎么界定细节?为什么说learns little semantic variation?首先什么是semantic variation?它怎么学?体现学习的结果是什么?甚至于什么是variation?我反复看到但是始终无法理解它的含义。中文一言以蔽之就是变化,可是在数学上它是有特定含义的吧?我在线性代数的定义看到
      A variation is a relation between a set of values of one variable and a set of values of other variables.
      这个在我看来更像是映射的定义? 这里的定义似乎更加的详细:
      In problems relating to two or more variables, it is seen that the value of a variable changes with the change in the value ( or values ) of the related variable (or variables). Suppose a train running at a uniform speed of v km./h. travels a distance of d km. in t hours. Obviously, if t remains unchanged then v increases or decreases according as d increases or decreases. But if d remains unchanged, then v decreases or increases according as t increases or decreases. This shows that the change in the value of a variable may be accompanied differently with the change in the values of related variables. Such relationship with regards to the change in the value of a variable when the values of the related variables change, is termed as variation.
      在概率论里我们定义随机变量的前提是有一个所谓的随机过程,所以,我们可以相类似的定义一个相关变量的数值变化而引起的一个变化过程,我们关注的是相关变量数值变化的对应关系。我想中文的所谓的简而言之的变化似乎遗漏了巨大的特定数学含义吧?
    3. 为什么说semantic and conceptual composition of the data就是semantic compression?什么地方体现了压缩呢?semantic和conceptual composition of data分别指的是什么?
  2. 线性代数的继续学习一旦中断就被忘记了。以后吧。原因是我以为从根本上来说LoRA是一个改进,而目前要了解最根本的原理比了解改进来的重要的多。并且这个都是如何实现改进的细节,先放一放吧。
  3. 我如果看完论文依然不能回答这些问题那就是失败。作者写了他们研究的动机:
    We thus aim to first find a perceptually equivalent, but computationally more suitable space, in which we will train diffusion models for high-resolution image synthesis.
    要记住这个就是所谓的latent space的由来,就是从识别的角度来看是等价的但是计算量小的多的空间。
  4. we train an autoencoder which provides a lower-dimensional (and thereby efficient) representational space which is perceptually equivalent to the data space.
    这个部分回答了之前的问题,lower-dimensional representational space当然是目的,只有降低维度才能降低计算量,从向量的角度来看当然就是减少其中的元素。矩阵就复杂一些,LoRA的就是一种比较高级的降低维度的技巧。但是怎么能够做到perceptually equivalent呢?关键是这里。
  5. Importantly, and in contrast to previous work, we do not need to rely on excessive spatial compression, as we train DMs in the learned latent space, which exhibits better scaling properties with respect to the spatial dimensionality. The reduced complexity also provides efficient image generation from the latent space with a single network pass. We dub the resulting model class Latent Diffusion Models (LDMs).
    这个是十分重要的总结,就是在实现手段上一开始就否定了方法的本质不是所谓的空间压缩,这个是太低级了?因为传统的压缩是欺骗眼睛,当然眼睛背后是用来识别的大脑。我的理解就好像说普通的视频压缩对于大脑来说还是无损的压缩,故而压缩的力度还不高,而从generative的角度来看不需要这么高保真,可以失去更多的细节只留下概念性的部分?这些是我的猜测,在后面的阅读看看对不对?同时最重要的是这里点出了模型的名称LDM
  6. A notable advantage of this approach is that we need to train the universal autoencoding stage only once and can therefore reuse it for multiple DM trainings or to explore possibly completely different tasks
    这里点出了模型的可复用性让我有些吃惊,难道这不就是模型的意义吗?能够复用,否则为什么叫做模型呢?难道之前的所谓的模型是不可复用的?或者说之前的智能学习还没有建立可复用的模型?让我们再次学习autoencoder的定义
    An autoencoder is a type of artificial neural network used to learn efficient codings of unlabeled data (unsupervised learning). An autoencoder learns two functions: an encoding function that transforms the input data, and a decoding function that recreates the input data from the encoded representation. The autoencoder learns an efficient representation (encoding) for a set of data, typically for dimensionality reduction.
    所以,这个是在unsupervised learning阶段的分类标签学习过程,目的是建立降维打击手段得到的输入数据的表达方式,同时能够完满的逆过程把输入数据再用降维后的表达来还原。这个就是一个高级的识别过程,因为真正的认知不是简单的像素级的细节比对,也不是简单的猫有四条腿,狗有四条腿,所以猫就是狗,狗就是猫的简单特征推理。总之,真正的识别必然是去除大量不重要细节的抓主要矛盾的压缩,这个压缩的概念不同于数据的压缩而是在高维度到低维度的压缩,是概念性的提取特征,是不依赖于各种各样不同品种的狗的特征细节而能够一眼望去肯定的回答什么是一只狗的概念性压缩后的特征提取。我以为这个是非常的高级的智能学习步骤,因为几乎所有的智能过程都充斥着对象的识别与认知,而这个最最基本的功能是其他高级能力的基础。
  7. 进一步补习autoencoder的定义

    An autoencoder is defined by the following components:

    Two sets: the space of decoded messages X; the space of encoded messages Z. Almost always, both X and Z are Euclidean spaces, that is, X = Rm , Z = Rn for some m , n .

    Two parametrized families of functions: the encoder family Eϕ : X → Z, parametrized by ϕ ; the decoder family Dθ : Z → X , parametrized by θ .

    For any x ∈ X , we usually write z = Eϕ ( x ) , and refer to it as the code, the latent variable, latent representation, latent vector, etc. Conversely, for any z ∈ Z , we usually write x ′ = Dθ ( z ) , and refer to it as the (decoded) message.

    Usually, both the encoder and the decoder are defined as multilayer perceptrons. For example, a one-layer-MLP encoder Eϕ is:

    E ϕ ( x ) = σ ( W x + b )

    where σ is an element-wise activation function such as a sigmoid function or a rectified linear unit, W is a matrix called "weight", and b is a vector called "bias".

    这些是数学的严格定义,还有关于如何检验autoencoder的质量牵扯出了一个Gradient descent的概念。
  8. we design an architecture that connects transformers to the DM’s UNet backbone and enables arbitrary types of token-based conditioning mechanisms
    作者的设计的架构是什么意思?UNet的定义是什么?

二月二十一日 等待变化等待机会

  1. 论文作者自己宣称的贡献实际上是非常重要的部分,是理解这篇论文重要性的核心部分:
    1. In contrast to purely transformer-based approaches, our method scales more graceful to higher dimensional data and can thus (a) work on a compression level which provides more faithful and detailed reconstructions than previous work (see Fig. 1) and (b) can be efficiently applied to high-resolution synthesis of megapixel images. 这里的关键词是压缩方式的有效性,能够忠实还原是压缩的基本要求,压缩效率更高是其存在意义的基础。 压缩效果的比较是硬碰硬的指标,不论你的算法有多么高明,压缩率有多高,但是一旦你的还原质量不够,那几乎就立刻被判了死刑了。 这幅图是阅读理解的关键,而其中的含义是非常深刻的,我至今还是不能完全掌握。这里要先补课学习gradient的概念,一言以蔽之,
      A gradient is a derivative of a function that has more than one input variable.
      这个是它的定义,但是要真正理解它还需要理解它的作用:
      The gradient is the generalization of the derivative to multivariate functions. It captures the local slope of the function, allowing us to predict the effect of taking a small step from a point in any direction.
      说到底是给你一个工具来判断那个方向变化最快从而给你一个获取极值的方向。这个当然是局部优化的概念,但是通常简单有效。
    2. We achieve competitive performance on multiple tasks (unconditional image synthesis, inpainting, stochastic super-resolution) and datasets while significantly lowering computational costs. Compared to pixel-based diffusion approaches, we also significantly decrease inference costs.
      它的压缩效果是和谁相比?当然是和传统的像素空间,那里充斥了大量的无意义的细节,对于保持semantic并无多大帮助,这个也是引入latent space的最核心原因,这个也就是目前AGC能够流行起来的最根本原因。量变引发的质变,不要简单的认为一个压缩算法就不能带来革命,当前的人工智能大多数想法并不是什么绝对的新鲜概念,很多都是几十年前就有了,只不过当时的算力不足以支撑而不被看好,今天的想法也不是前人想不到只是认为当时的现实做不到而不被人看好而已。
    3. We show that, in contrast to previous work which learns both an encoder/decoder architecture and a score-based prior simultaneously, our approach does not require a delicate weighting of reconstruction and generative abilities. This ensures extremely faithful reconstructions and requires very little regularization of the latent space.
      这里的意义也是非常重大的,这里也许就是模型的本质意义,能够轻易的复用是一个模型的最根本的意义,不论多么复杂的训练过程,模型一旦完成,可以很简单的重复使用达到它的逆过程的还原而无需做过多的调整配置修改。这个是架构革命的重大创新,我的觉得这个意义是仅次于压缩的大贡献。
    4. We find that for densely conditioned tasks such as super-resolution, inpainting and semantic synthesis, our model can be applied in a convolutional fashion and render large, consistent images of ∼ 10242 px.
      它的应用场景也是其重大贡献,否则一个无用的发明不论多么精巧高明都是无意义的玩具而已,对于实际工作需要高强度的扩展这种最基本的需求的满足是足以夸耀的贡献!
    5. Moreover, we design a general-purpose conditioning mechanism based on cross-attention, enabling multi-modal training. We use it to train class-conditional, text-to-image and layout-to-image models.
      这里是非常的高级的功能,这个cross-attention是有一个核心的贡献,而它能够让多个模型同时训练更是超出我目前能够理解的范畴,这个需要在随后的阅读里深刻理解领会。难道可以把controlNet之类的形体指示,或者深度图之类的作为提示条件来综合训练?这个也是开创性的贡献。
    6. Finally, we release pretrained latent diffusion and autoencoding models at https://github.com/CompVis/latent-diffusion which might be reusable for a various tasks besides training of DMs
      还有什么共享更高尚的贡献呢?一个伟大的发明创造如果不是为了人类的共同福祉而共享,那么它的意义终将是有限的。更何况它的用途并不限于训练模型,这个更加令人神往。
  2. 所谓站在巨人的肩膀上,如果对于前人的工作不明白其优劣处,那谈何创新改进?非常多的人包括我自己都是在现有前人工作都不甚了了的情况下就空谈什么新方向,殊不知别人很可能已经走过或者其它方法早已解决了你所谓的不足只是你不知道而已。这里的总结言简意赅,我需要很多的理解:
    1. The high dimensional nature of images presents distinct challenges to generative modeling.
      这里开宗明义说出了问题和挑战,这才引出了各个方向方法的孰优孰劣。
    2. 惜秦皇汉武,略输文采;
      Generative Adversarial Networks (GAN) allow for efficient sampling of high resolution images with good perceptual quality, but are difficult to optimize and struggle to capture the full data distribution.
      GAN虽然不错,但是很难优化,而且不能掌握全部的数据分布。
    3. 唐宗宋祖,稍逊风骚;
      Variational autoencoders (VAE) and flow-based models enable efficient synthesis of high resolution images, but sample quality is not on par with GANs.
      VAE在我看来和作者的过程有着非常相似的部分,这个是需要格外注意理解的。
      Variational autoencoders are often associated with the autoencoder model because of its architectural affinity, but with significant differences in the goal and mathematical formulation. Variational autoencoders are probabilistic generative models that require neural networks as only a part of their overall structure.
      VAE似乎就是autoencoder,但是又不同?很复杂。
      The neural network components are typically referred to as the encoder and decoder for the first and second component respectively. The first neural network maps the input variable to a latent space that corresponds to the parameters of a variational distribution. In this way, the encoder can produce multiple different samples that all come from the same distribution. The decoder has the opposite function, which is to map from the latent space to the input space, in order to produce or generate data points. Both networks are typically trained together with the usage of the reparameterization trick, although the variance of the noise model can be learned separately.
      就是说VAE只是利用了autoencoder架构的encoder/decoder而已?很难理解其中的微妙区别。这里有大量的概率数学部分,照例我准本忽略,因为我的感觉实际上VAE的核心还是要假设prio和posterior的概率分布模型,这个直接关系到还原噪音的效果,到底是正态分布还是波努力分布这似乎要根据具体的现实吧?总之,我看起来很吃力。暂时先放一放吧。
    4. 一代天骄,成吉思汗,只识弯弓射大雕。
      While autoregressive models (ARM) achieve strong performance in density estimation, computationally demanding architectures and a sequential sampling process limit them to low resolution images. Because pixel based representations of images contain barely perceptible, high-frequency details, maximum-likelihood training spends a disproportionate amount of capacity on modeling them, resulting in long training times. To scale to higher resolutions, several two-stage approaches use ARMs to model a compressed latent image space instead of raw pixels.
      说老实话,我根本不明白autoregressive (AR) modelVariational autoencoders (VAE)到底有什么不同?这里的回答比较清楚

      Autoregressive models are basically modeling a time series, or a random process. They can be used in VAEs as well, which is what happens in the case of text, the decoder models p(x|z) in an autoregressive way, i.e the current word to be predicted is dependent on the previously predicted words.

      Variational Autoencoders are a general representation learning and generative modeling framework, they try to model your data, by learning a latent variable representation p(z|x) and then generate p(x|z). They use variational inference to estimate these distributions accurately. i.e they assume a general class of distributions and then use an optimization scheme to find parameters that allow them to match the target distribution well.

      The idea behind normalizing flows is that given a simple distribution, you can perform invertible transformations on them to get more complex distributions, if you can compute the log probabilities of these transformed distributions efficiently, then basically you can perform variational inference with more complex distributions, which might help.

      Looking at the definitions it is clear that all of them are interconnected, you can use normalizing flows to improve the class of distributions you are using in a VAE, you can use an autoregressive decoder to generate p(x|z) if your data is sequential.

      能不能理解,虽然autoregressive指的是泛泛的概率模型,但是VAE更加具体是一个和时间相关的随机过程,而flow-based model更像是一个原则性的假设你能够根据逆过程计算原本的概率分布,这个似乎是encoder/decoder的理论基础?总之,它们是非常紧密联系的,这是我唯一能够确定的。
    5. 俱往矣,数风流人物,还看今朝。 作者的细节描述是很复杂的我基本上看不懂,只有一点似乎可以明白一点,就是因为训练是在低维度的latent space,所以,大大降低了计算需求,这个公式有一个细小的变化。
      L DM = E ε(x),ε∼N (0,1),t [ ||ε - ε Θ ( x t ,t) || 2 2 ]
      就是说从x变成ε(x)是大大减少了计算强度。
    这里补习一下概念Fréchet inception distance (FID)
    The Fréchet inception distance (FID) is a metric used to assess the quality of images created by a generative model, like a generative adversarial network (GAN). Unlike the earlier inception score (IS), which evaluates only the distribution of generated images, the FID compares the distribution of generated images with the distribution of a set of real images ("ground truth").
  3. 看论文非常的难,只能由浅入深,逐步反复,我想目前还是忽略实现细节,领会论文的贡献和原理吧。它所引用的大量文献是接下来阅读的一个方向,否则这样子看论文是对作者的不尊重:你能够在没有了解引用的论文的基础上就明白这篇论文岂不是说你比作者更强吗?这是多么的荒谬而且不严肃。先休息一下吧。
  4. 看到老爸发来的《枕上诗书》非常优美:
    千人同尝不同味,
    万人同道不同心。
    有人理解我之幸,
    无人理解我独行。
    知我者慰我心忧,
    不知我者谓我何求?
    世间万物皆可有,
    唯有懂字最难求。
    

二月二十二日 等待变化等待机会

  1. 顺便记录一个视频,算是说Sora的比较靠谱的.
  2. 这篇Attention is all you need论文也是一片非常重要的论文。这个应该是所谓的Transformer的最早提出的。
    A transformer is a deep learning architecture based on the multi-head attention mechanism, proposed in a 2017 paper "Attention Is All You Need". It has no recurrent units, and thus requires less training time than previous recurrent neural architectures, such as long short-term memory (LSTM), and its later variation has been prevalently adopted for training large language models on large (language) datasets, such as the Wikipedia corpus and Common Crawl. Input text is split into n-grams encoded as tokens and each token is converted into a vector via looking up from a word embedding table. At each layer, each token is then contextualized within the scope of the context window with other (unmasked) tokens via a parallel multi-head attention mechanism allowing the signal for key tokens to be amplified and less important tokens to be diminished. The transformer paper, published in 2017, is based on the softmax-based attention mechanism proposed by Bahdanau et. al. in 2014 for machine translation, and the Fast Weight Controller, similar to a transformer, proposed in 1992.
    所以,这里究竟有多少概念需要学习呢?
    1. 首先Transformer它是一个架构而不是一个模型,因为模型这个中文词有时候会被理解为某种架构的含义。它不是数据模型,而是针对RNN的一种变革。而且它是attention机制。当然这个定义也是不妥的,因为一个架构必然对应某种类型的数据存储格式,所以,Transformer也必然有其对应的数据模型,只不过,所谓的模型只有当它的训练结果能够轻而易举的复用作为检验或者应用的时候才能称之为模型,否则就是一些内部存储的原始数据而已。
    2. 要补习的基础知识太多了,什么是Outer Product呢?它的现实意义是什么呢?不同于寻找两个向量方向差异的点乘,外乘代表了两个向量空间的融合或者是交锋,因为结果是一个矩阵,它代表了两个向量在每一个维度上的比较。
      Given two vectors of size m × 1 and n × 1 respectively, u = [ u1 u2 . . . um ] , v = [ v1 v2 . . . vn ] their outer product, denoted u ⊗ v , is defined as the m × n matrix A obtained by multiplying each element of u by each element of v : u v = A = [ u1 v1 u1 v2 . . . u1 vn u2 v1 u2 v2 . . . u2 vn . . . . . . . . . . .. um v1 um v2 . . . um vn ] Or, in index notation: ( u v ) i j = u i v j
    3. 这里是Mathtml的官方网页,至少我看是比较靠谱?花这么多时间去学习简单的mathtml实际上也是一种加深记忆的过程。
    4. 那么什么是RNN呢?这里的一个解释定义似乎是比较准确了。
      A recurrent neural network (RNN) is a type of artificial neural network which uses sequential data or time series data. These deep learning algorithms are commonly used for ordinal or temporal problems, such as language translation, natural language processing (nlp), speech recognition, and image captioning; they are incorporated into popular applications such as Siri, voice search, and Google Translate. Like feedforward and convolutional neural networks (CNNs), recurrent neural networks utilize training data to learn. They are distinguished by their “memory” as they take information from prior inputs to influence the current input and output. While traditional deep neural networks assume that inputs and outputs are independent of each other, the output of recurrent neural networks depend on the prior elements within the sequence. While future events would also be helpful in determining the output of a given sequence, unidirectional recurrent neural networks cannot account for these events in their predictions.
      这里要注意的是结果也能再影响下一次的输入结果,似乎预示着某种动态的模型?也许这个就是其中提到的时间敏感性的意思?wiki的解释一般更加的权威,而且把CNN放到一起来对比是更加的精准全面。
      A recurrent neural network (RNN) is one of the two broad types of artificial neural network, characterized by direction of the flow of information between its layers. In contrast to the uni-directional feedforward neural network, it is a bi-directional artificial neural network, meaning that it allows the output from some nodes to affect subsequent input to the same nodes. Their ability to use internal state (memory) to process arbitrary sequences of inputs makes them applicable to tasks such as unsegmented, connected handwriting recognition or speech recognition. The term "recurrent neural network" is used to refer to the class of networks with an infinite impulse response, whereas "convolutional neural network" refers to the class of finite impulse response. Both classes of networks exhibit temporal dynamic behavior. A finite impulse recurrent network is a directed acyclic graph that can be unrolled and replaced with a strictly feedforward neural network, while an infinite impulse recurrent network is a directed cyclic graph that can not be unrolled.
      流动是双向的?反复看到所谓的Long short-term memory
      Long short-term memory (LSTM)[1] network is a recurrent neural network (RNN), aimed to deal with the vanishing gradient problem present in traditional RNNs. Its relative insensitivity to gap length is its advantage over other RNNs, hidden Markov models and other sequence learning methods. It aims to provide a short-term memory for RNN that can last thousands of timesteps, thus "long short-term memory".
  3. 我学习这些基本概念的意义目的在哪里?显然不是为了学术研究,是为了帮助理解用途?照理说这个目的性非常容易满足,可是关键是到什么程度?能不能把各个相关联的概念串起来理解也许就是检验我的学习效果的标准吧?只不过缺失的链条与基础太多了,任何一句阅读都往往碰到一大堆的似曾相识,甚至完全陌生的概念与名词。这个也是大多数人在这个领域遇到的困难吧?毕竟这些是积累了几十年的研究成果演化而来的,很多人为此付出毕生的努力才前进一小步,而我等贩夫俗子想要在短时间内站在巨人的肩膀上那是痴心妄想。
  4. 针对最近很火爆的Sora的现象级热评,我希望我也能看到它的真实的内在机制,但是没有基础只能人云亦云。我觉得还是要深刻深入理解到底什么是transformer的机制,只有从最根本的基础开始才有可能理解发展的现状和方向。

二月二十三日 等待变化等待机会

  1. 这篇论文开宗明义的介绍之前的模式的核心问题运用了高度的概括和抽象,这个是对于初学者来说很难深刻理解的,但是这种提纲挈领式的总结也是最好的见面礼,因为我读了几遍定义也不如这一段话来的更加的一针见血。
    Recurrent models typically factor computation along the symbol positions of the input and output sequences. Aligning the positions to steps in computation time, they generate a sequence of hidden states ht , as a function of the previous hidden state ht−1 and the input for position t. This inherently sequential nature precludes parallelization within training examples, which becomes critical at longer sequence lengths, as memory constraints limit batching across examples.
    它点出了attention不,应该说是recurrent机制,因为attention是这篇论文提出的,而这个上下文敏感机制在我看来被说成是attention机制是非常恰如其分的,在《Yes,Minister》里普通选民对于政治家的演讲的注意力就只有三秒,一旦把一个观点分在两句话里讲的话,听众就会忘记上一句是什么意思,这个就是attention的核心思想,因为人们一次性输入语言的处理的带宽是有限甚至是固定的,导致超过这个时长或者带宽就必须忘记,这个在recurrent/attention实现里有着非常生动的体现,所以,attention并不是完全摒弃recurrent模式,而是为了效率把输入性的依赖剔除了,这个是它的天才的做法,当然也是非常自然的做法,因为为了能够并行处理。机制,或者还不如说是recurrent模式本身固有的机制:当前状态是关于当前输入和之前的状态的函数。这个模式本身本来是对于表达上下文敏感性过程的一个很好的方案,但是它固有的上下文依赖性导致对于计算资源成为瓶颈:内存是有限的,并行计算要求摆脱过多的依赖性。
  2. 那么作者的最重要的贡献是什么呢?
    Transformer, a model architecture eschewing recurrence and instead relying entirely on an attention mechanism to draw global dependencies between input and output.
  3. 但是还是要补习概念,要理解RNN就要先明白CNN做了什么,以及能做什么?
    Convolutional neural network (CNN) is a regularized type of feed-forward neural network that learns feature engineering by itself via filters (or kernel) optimization. Vanishing gradients and exploding gradients, seen during backpropagation in earlier neural networks, are prevented by using regularized weights over fewer connections.
    这里的关键字是什么呢?依赖filter优化。而为什么它是convolution机制呢?我之前一直不太理解,现在有些明白这个是模仿人类五官尤其是视觉作为传感器采集外界光能量刺激的机制,所谓的convolution计算的是光通量,这就是理解的核心,因为积分机制原本就是研究过程累积的数学方式,那么这个方案它的前提就是和平面以及时序紧密关联的,这是纯粹的依靠视觉来理解人类识别的路径。而RNN则至少是更加的抽象了一层,因为不论你的眼睛作为传感器采集的具体光信号的总和要怎样存储,最终抽象出来的信号提取,或者是特征提取都是向量来存储,因为即便是向量空间也不过是一族向量,在本质上不需要强加的空间强相关性,因为在向量空间里的basis是唯一能够识别的基础向量,它们的顺序似乎是不重要的,我以为这个才是处理提纯过的本征信号。那么作为一般性的思想,CNN要去除空间干扰,RNN去除时序敏感性,这些都是对于一个过程的信号总量采集之后的特征提取方式不同而已。
  4. 模式是否一定必须是Feed-Forward Neural Network呢?这个是反映了人类神经元系统的特征还是说仅仅因为当时对于处理反馈机制的资源不足的体现而化简模型呢?我直觉以为不应该过于固化某种固定机制,人类神经元或者自然形成的机制应该是通过巨大时间维度筛选出来的,而筛选过程应该有尝试多种机制,唯一存活的标准是有效性和稳定性以及发展性。如果一个机制不能还原抽象或者说提取的特征回到本来的客观现实,那么就无法验证抽象的可靠性,那么它就是无效或者说无用的;同样的如果还原过程的不稳定和不可靠是一个质量衡量标准;那么发展性要求的是这个抽象还原机制有自我提高的机制,也就是学习性,能够随着训练数量的增长而提高有效性与可靠性,这个正增长机制不论多么微不足道随着训练数量的增加它一定能够达到某种质的飞跃,也就是增长或者学习能力的几何级数的增加。这个是正反馈的机制。
  5. 如果要对于人类的学习能力有更深刻的理解的话应该要去研究人脑机制。这个真的是无穷无尽的海洋啊。
  6. 很容易就被带偏的原因是每一句都是大量的概念,很多都是闻所未闻,当然这也取决于到底能够领会多少,学习的目的和目标是什么?在不确定不明确的情况下,四处遨游也是一种吸收养分水分的最好的模式,重要的往往被反复强调与引用,那么在多篇论文反复强调引用的东西往往是重要的。而重要的东西往往是可以被反复灌输的,所以,这个机制是自然而然的过滤或者说自然反馈加强的机制。
  7. 神经网络为什么是一个天然的计算机制呢?它的智能表达机制来源于哪里呢?这个图解说明是非常好容易理解什么是人类识别的模式,至少是我们现在认为的机制吧? 如果自然界的确能够被细分为一个个所谓的feature或者说特征,那么识别特征就是识别对象的简单组合。而神经网络基于光通量来过滤所谓的杂音之后的坚强的连接自然而然的成为下一次识别或者说还原的快车道。自然往往选择最简单可靠的路径,人们总结为奥卡姆剃刀原则,因为精锐所以锋利,从哪里来就回哪里去:From light to darkness; From darkness, light!既然光信号经过损耗杂音干扰后存留的信号肯定是本征信号,那么反复出现的就必然是本征信号。我们需要解决的往往是怎么最大限度的模拟信号的损失而又能够尽可能的还原,这里说是还原还不如说是经过检验可以接受就算成功。人类的反馈外界客观世界的唯一标准就是有用,画画像不像是由谁决定的?是通过比较来决定的,这个图灵实验是一个原理,没有什么数学方法来定义这个复制是否可信,只能用使用者能否发现区别来作为检验的唯一标准:实践是检验真理的唯一标准,人如果是唯一的实践者,人就是检验的唯一标准。如果学习的机器是唯一的实践者,那么让机器来做机器的检验者吧。
  8. 想要理解神经网络需要先理解为什么其他方案失败了。Perceptron可能是任何普通人都能够理解的最理想的也是最简单的方案,如果这个机制能行,人工智能也许真的明天就能来临,因为我们的目前的计算机架构本身就是最典型的Perceptron,只要你能够被输入到计算机那么一定是被数学严格定义的,那么就是可以做到二元可识别的。能够识别自然能够被联系,能够被联系自然能够被反馈,那么认识世界,改造世界的闭圈循环就形成了。这个是理想。 我以为这个对于客观复杂世界作出机械刻板一比一复刻的思路是过于天真的,因为现实是资源永远是有限的宝贵的,而自然界的信息几乎是无穷的,以有限的处理能力硬抗无限的输入信息是徒劳的。人类智能进化史就是压缩还原的不断自我平衡,去粗取精,去伪存真的真正目的是自然处理能力的不足。同样的,现在人类发明的种种算法也是现实的计算能力与客观处理的要求的之间的矛盾的某种妥协产物,如果有一天在虚拟现实里实现真正的Perceptron我也不会感到惊奇,但是不是现在。
  9. 为什么不能处理XOR呢?看来神经网络的可计算性是经过了严格的数学证明了,这个正像计算机架构归根结底是图灵机一样,那么它的可计算性也是经过了严格的数学证明的。
  10. 累了。休息吧。

二月二十四日 等待变化等待机会

  1. 如果你自己坚信了,那么很多时候别人也相信了。这在以前被称之为信念,很多时候是一种从众心理,因为人不可能处处时时都亲自实践,那么间接学习就是一个明智的选择,也就是说我们常常会不自觉的相信我们的同类的经验。久而久之,经验被传递了,尽管没有被亲自验证,以至于很多的传说传统就是这么来的。
  2. 单单理解Transformer就需要理解这篇论文,我看了三天还在看引言:
    ...the number of operations required to relate signals from two arbitrary input or output positions grows in the distance between positions...This makes it more difficult to learn dependencies between distant positions. In the Transformer this is reduced to a constant number of operations, albeit at the cost of reduced effective resolution due to averaging attention-weighted positions, an effect we counteract with Multi-Head Attention...
    这里说的是什么呢?就是核心的问题是位置。如果没有位置,那么一切都是非常简单的,我的理解位置是核心因为上下文敏感本质上就是位置敏感,而所谓的上下文那更加是一个资源与准确性平衡的结果,目前的概率模型是类似于条件概率,那么多大的前置条件要纳入条件呢?无限大的上下文敏感自然是无限,可是可能吗?所以,要引入上下文的一个类似于活动窗口(attention),但是一词多义就是很典型的上下文敏感,要解决这个问题依靠的是什么办法呢?
    Self-attention, sometimes called intra-attention is an attention mechanism relating different positions of a single sequence in order to compute a representation of the sequence.
    这里的所谓的self-attention就是把上下文限制在输入?为什么引入上一次的输出也作为上下文的一部分呢?我感觉这个想法是非常的聪明的,上一次的结果是上一次上下文的结果但是从attention的角度来看它会作为一个潜在的变量影响到下一次的结果,这个本身就是上下文,而且是非常聪明的把几乎无限的前置输入做了一个限制,也就是把上一次的活动窗口的结果作为前置输入,这个是很自然的。从数学上看像是递归函数,很优美的一个表达。
  3. The Transformer is the first transduction model relying entirely on self-attention to compute representations of its input and output without using sequence-aligned RNNs or convolution.
    我始终对于transduction model很在意,因为我对于它很敬畏,维基百科说它的每一次变动都要重新训练,这个不知道是不是我理解错误了?这里点出了Transformer的本质是抛弃了顺序相关的传统做法。
  4. 这里是关于模式的高度概括:
    Most competitive neural sequence transduction models have an encoder-decoder structure. Here, the encoder maps an input sequence of symbol representations (x1 , ..., xn ) to a sequence of continuous representations z = (z1 , ..., zn ). Given z, the decoder then generates an output sequence (y1 , ..., ym ) of symbols one element at a time. At each step the model is auto-regressive, consuming the previously generated symbols as additional input when generating the next.
    重温一下transformer model的架构。 最后一句最重要,上一次产生的符号会作为额外的输入。这个思想就是解决无限上下文难题的核心。但是所有的秘密也都在于这里。
  5. 魔鬼在细节的原因在与大多数人对于宏观抽象的为什么以及什么都能理解,但是到了怎么做就触礁沉没了。因为归根到底前者是为了方便理解而降低了复杂度的高度概括,你即便没有完全理解也不一定会被人看出来。可是一旦到了具体实作阶段就再也来不得半点模糊,因为每一步的理解可能都是下一步的输入,这个正好就是Transformer的模型的要义,而机器学习和人类的学习本质上是一回事,结合自己的学习过程就能理解它的核心:
    Encoder: The encoder is composed of a stack of N = 6 identical layers. Each layer has two sub-layers. The first is a multi-head self-attention mechanism, and the second is a simple, position-wise fully connected feed-forward network. We employ a residual connection around each of the two sub-layers, followed by layer normalization. That is, the output of each sub-layer is LayerNorm(x + Sublayer(x)), where Sublayer(x) is the function implemented by the sub-layer itself. To facilitate these residual connections, all sub-layers in the model, as well as the embedding layers, produce outputs of dimension dmodel = 512.
    这里字字珠玑,信息量非常的大,因为它肯定是非常的复杂,否则也不可能有那么神奇的效果。只能慢慢的消化了。这个还仅仅是encoder。
  6. Decoder: The decoder is also composed of a stack of N = 6 identical layers. In addition to the two sub-layers in each encoder layer, the decoder inserts a third sub-layer, which performs multi-head attention over the output of the encoder stack. Similar to the encoder, we employ residual connections around each of the sub-layers, followed by layer normalization. We also modify the self-attention sub-layer in the decoder stack to prevent positions from attending to subsequent positions. This masking, combined with fact that the output embeddings are offset by one position, ensures that the predictions for position i can depend only on the known outputs at positions less than i.
    这个比encoder更难懂,而且为什么说六层是identical呢?结合架构图我很难理解六层在哪里?
  7. Attention是什么呢?
    An attention function can be described as mapping a query and a set of key-value pairs to an output, where the query, keys, values, and output are all vectors. The output is computed as a weighted sum of the values, where the weight assigned to each value is computed by a compatibility function of the query with the corresponding key.
    这里的定义非常的复杂,我只能说现在终于正式看到了QKV这个定义了。在架构图上看到过它们,不理解是什么,现在看来这个是一个函数,函数的值是一个相当复杂的就在于说这里的weight是什么角色和用意呢?因为如果没有这个weight简单的query/key pair几乎是任何学过计算机的人都能明白的,几乎就是传统的数据库查询的原理,可是有了这个weight据说还要和query/key关联,那么这么做的用意是什么呢?
  8. 再次重温一下softmax的概念,虽然我觉得用脚趾头都能理解了,但是很容易模糊。
    The softmax function, also known as softargmax or normalized exponential function, converts a vector of K real numbers into a probability distribution of K possible outcomes.
    单单使用看起来是很简单的,但是它的真正含义却很深奥
    It is a generalization of the logistic function to multiple dimensions, and used in multinomial logistic regression.
    这里为什么是Logistic function?它的最早引入是和预测人口增长的:
    The initial stage of growth is approximately exponential (geometric); then, as saturation begins, the growth slows to linear (arithmetic), and at maturity, growth stops.
    这个似乎是一种人们对于事物发展的一般规律的描述,任何一个新事物或者新刺激,在一开始的时候增长都是几何级数的,随着时间的推移,增长变缓慢了成为线性增长,最后停滞了。我喜欢它的标准公式:
    f ( x ) = 1 1 + e -1 = e x e x + 1
    后面这个形式更加的直观:一个以指数增长的事物它的可持续增长的概率是怎么样子的呢?很明显的一个国家的GDP增长就是这个典型,在初期指数增长的确很快,但是增长越大基数越大意味着后续增长的动力越来越相对变弱,最后高增长变成低增长以至于零增长甚至倒退。我觉得选取这个概率模型来表示信号处理强度是恰如其分的,一个信号刺激的烈度逐步减退也是如此的,至于为什么是指数我的理解可以看作是维度的增加,这个在图形里是显而易见的,曝光的过程就是面积的增大,自然而然的维度增大,当然就是指数的增长,这个从convolution的概念就是一个体现。
  9. Scaled Dot-Product Attention:The input consists of queries and keys of dimension dk , and values of dimension dv . We compute the dot products of the query with all keys, divide each by dk , and apply a softmax function to obtain the weights on the values.
    这个是原理 真正的跨越是并行计算,而这其中的道理却又出奇的简单,看起来伟大的跳跃都只不过是平时散步的时候把脚尖颠起来走一走而已。就是说原本是一个个向量的计算,现在换成了矩阵,那么可以利用计算机的矩阵计算优化一个个单独的向量计算,尤其是高维度的矩阵。
    In practice, we compute the attention function on a set of queries simultaneously, packed together into a matrix Q. The keys and values are also packed together into matrices K and V . We compute the matrix of outputs as: Attention ( Q,K,V ) = softmax ( Q K T d k ) V
  10. 后面的Muti-Head Attention机制就更加的复杂了。先休息一下吧。我以为我看不懂细节的原因在于我不明白新的实现是对于旧机制的改进而我连旧的机制都不明白,所以,应该从旧的机制来学习。
  11. 那么是不是应该把著名的论文都先浏览一下有个概念再说呢?我感觉这个领域里著名的论文就如同经典著作一样必须熟读,因为大部头的古老的教科书式的书籍很多都是很多年前的著作,和时代离得有些远了。这里是21篇最多引用的论文,我先来看看。我感觉这个标准似乎不好,因为单单的引用有时候不能完全反映它的重要性。
    1. Deep Residual Learning for Image Recognition
    2. ImageNet Classification with Deep Convolutional Neural Networks
    3. ADAM: A METHOD FOR STOCHASTIC OPTIMIZATION
    4. Random Forests
    5. VERY DEEP CONVOLUTIONAL NETWORKS FOR LARGE-SCALE IMAGE RECOGNITION
    6. Support-Vector Networks
    7. LIBSVM: A Library for Support Vector Machines
    8. Scikit-learn: Machine Learning in Python
    9. Deep learning
    10. Gradient based learning applied to document recognition
    11. Latent Dirichlet Allocation
    12. Generative Adversarial Nets
    13. Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks
    14. Going Deeper with Convolutions
    15. ImageNet: A Large-Scale Hierarchical Image Database
    16. TensorFlow: A system for large-scale machine learning
    17. MapReduce: Simplified Data Processing on Large Clusters
    18. Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift
    19. Dropout: A Simple Way to Prevent Neural Networks from Overfitting
    20. Bagging Predictors
    21. ImageNet Large Scale Visual Recognition Challenge
  12. 补习一个基本概念overfitting,这个我之前确实没有看懂。
    Overfitting is an undesirable machine learning behavior that occurs when the machine learning model gives accurate predictions for training data but not for new data. When data scientists use machine learning models for making predictions, they first train the model on a known data set. Then, based on this information, the model tries to predict outcomes for new data sets. An overfit model can give inaccurate predictions and cannot perform well for all types of new data.
    简而言之,就是测试不尽如人意。原因吗?
    • The training data size is too small and does not contain enough data samples to accurately represent all possible input data values.
    • The training data contains large amounts of irrelevant information, called noisy data.
    • The model trains for too long on a single sample set of data.
    • The model complexity is high, so it learns the noise within the training data.
    这里甚至有对于单个训练数据过长时间训练的问题!这个真的是有趣。总而言之,只能归罪于训练数据质量不高,否则你还能说是训练过程有错误?所以是单个数据重复训练?
  13. 这里是另一个概念的学习ensemble learning
    Ensemble learning is a machine learning technique that enhances accuracy and resilience in forecasting by merging predictions from multiple models. It aims to mitigate errors or biases that may exist in individual models by leveraging the collective intelligence of the ensemble.
    三个臭皮匠,顶个诸葛亮。
  14. 什么是Support vector machine呢?
    In machine learning, support vector machines (SVMs, also support vector networks[1]) are supervised max-margin models with associated learning algorithms that analyze data for classification and regression analysis.

    In addition to performing linear classification, SVMs can efficiently perform a non-linear classification using what is called the kernel trick, implicitly mapping their inputs into high-dimensional feature spaces. SVMs can also be used for regression tasks, where the objective becomes ϵ-sensitive.

    如果这里看的云里雾里,这里的例子就很清楚了
    In the case of support vector machines, a data point is viewed as a p-dimensional vector (a list of p numbers), and we want to know whether we can separate such points with a ( p − 1 ) -dimensional hyperplane. This is called a linear classifier.
    简而言之,降维!分类!
    H1 does not separate the classes. H2 does, but only with a small margin. H3 separates them with the maximal margin.
  15. 这个ReLU(rectified linear unit)概念是很明显的三极管的开关一类功能。
    In the context of artificial neural networks, the rectifier or ReLU (rectified linear unit) activation function f ( x ) = x + | x | 2 = { x if x > 0 0 otherwise
  16. 我觉得可能只有这篇Deep Learning论文值得仔细阅读。还有其他Lecun的论文。 Text Understanding from ScratchLearning in High Dimension Always Amounts to ExtrapolationEMP-SSL: TOWARDS SELF-SUPERVISED LEARNING IN ONE TRAINING EPOCH

    不过我感觉这个也不是好办法,因为似乎Yann LeCun后来在很多论文上署名是一种背书的意义。大家应该都争先恐后把他拉在论文的署名最后,而他也很随和乐意。


二月二十五日 等待变化等待机会

  1. 昨天下载了很多论文,今天要上传,找了一个前天的文件做参照:
    
    for file in $(find stable-diffusion/*.pdf -cnewer stable-diffusion/1706.03762.pdf); do name=$(basename $file) && s3cmd put --mime-type='application/pdf' stable-diffusion/$name s3://www.staroceans.org/stable-diffusion/$name; done
    
  2. 这篇论文标题很有意思:Eyes Wide Shut? Exploring the Visual Shortcomings of Multimodal LLMs。这篇论文有趣的是它提出了一个问题,就是CLIP模型可能固有的缺陷,就是它的encoding结果对于某些特征是无视的,或者说盲点。而发现这些盲点是一个不容易的过程,作者提出了一个实践的方法,就是寻找一个纯视觉训练的模型,这是因为作者认为这些盲点可能是语言大模型带给视觉模型的,所以,找到纯视觉模型能够看出区别而CLIP不能的样本,这个思路是很好的,因为这个是多模型所带来的问题。这篇论文的好的地方是它指示了一些别的论文能够得到的开源模型能够进行实验的方向。
  3. 我昨天翻看那些十几年前的convolution方法的论文模糊记得我十几年前也翻看过,所以,和今天的做法可能是有了很多的不同了,究竟怎么从image-space到latent-space的跳跃的呢?这个我依然不明所以然。
  4. 所以要理解之前的CLIP的问题,首先要明白CLIP的由来。Learning Transferable Visual Models From Natural Language Supervision
  5. 先补习一下概念Zero-Shot Transfer 我怎么觉得这个就是transduction的定义呢?
    Zero-shot learning (ZSL) is a problem setup in deep learning where, at test time, a learner observes samples from classes which were not observed during training, and needs to predict the class that they belong to. Zero-shot methods generally work by associating observed and non-observed classes through some form of auxiliary information, which encodes observable distinguishing properties of objects. For example, given a set of images of animals to be classified, along with auxiliary textual descriptions of what animals look like, an artificial intelligence model which has been trained to recognize horses, but has never been given a zebra, can still recognize a zebra when it also knows that zebras look like striped horses. This problem is widely studied in computer vision, natural language processing, and machine perception.
    这个描述的是学习过程的设置,但是它要解决的问题的本质是transduction。2008n年提出的时候乘坐dataless classification
    In computer vision, zero-shot learning models learned parameters for seen classes along with their class representations and rely on representational similarity among class labels so that, during inference, instances can be classified into new classes.
    这怎么看都是类比,就是举一反三。
    Unlike standard generalization in machine learning, where classifiers are expected to correctly classify new samples to classes they have already observed during training, in ZSL, no samples from the classes have been given during training the classifier. It can therefore be viewed as an extreme case of domain adaptation.
    核心要义就是要分类的是绝对没有训练过的类别。可以理解为移花接木式的运用已经学习的分类来做新的分类,这个半主动学习如果成功,机器学习当然可以半自动学习了,那效率自然大为提高了。
    • Learning with attributes: classes are accompanied by pre-defined structured description. For example, for bird descriptions, this could include "red head", "long beak". These attributes are often organized in a structured compositional way, and taking that structure into account improves learning.While this approach was used mostly in computer vision, there are some examples for it also in natural language processing.
    • Learning from textual description. As pointed out above, this has been the key direction pursued in natural language processing. Here class labels are taken to have a meaning and are often augmented with definitions or free-text natural-language description. This could include for example a wikipedia description of the class.
    • Class-class similarity. Here, classes are embedded in a continuous space. a zero-shot classifier can predict that a sample corresponds to some position in that space, and the nearest embedded class is used as a predicted class, even if no such samples were observed during training.
    应该是最后的class-class similarity是我理解的CLIP的机制吧?

二月二十六日 等待变化等待机会

  1. 这篇Deep Learning论文依然是很难的,尽管它看起来更像是一个全揽,对于历史的总结,可是我还是缺乏基本的概念掌握。对于十几年前的convolution的体系这里是一点点的领会:
    1. First, in array data such as images, local groups of values are often highly correlated, forming distinctive local motifs that are easily detected.
    2. Second, the local statistics of images and other signals are invariant to location. In other words, if a motif can appear in one part of the image, it could appear anywhere, hence the idea of units at different locations sharing the same weights and detecting the same pattern in different parts of the array. Mathematically, the filtering operation performed by a feature map is a discrete convolution, hence the name.
    所以,这个就是当年这个思路成功的根本原因,在人类视觉识别过程中,小块的图像的识别,或者说pattern的识别肯定是最最核心的部分,而这个是依赖于这种特征的大量的出现在训练过程,并且它的出现的方位却是随机无规律的,这个是显而易见的,人眼如同摄像机,在不断变换方位角度对于同一个对象的审视自然会在不同的方位得到同一影像特征块。至于说这个印象块要多小这个倒是一个细节问题,太大太小都是一个问题。
  2. 之前对于反复提到的pooling layer一直不理解它的作用,这里有一个解读:
    Although the role of the convolutional layer is to detect local conjunctions of features from the previous layer, the role of the pooling layer is to merge semantically similar features into one.
    在很多软件应用层里有去重,而这里我们希望发现重复并且反复引用它,这正好相压缩算法寻找重复的字符串一样,某种意义上说学习就是一个寻找最大限度压缩的办法。否则不是因为记忆有限,为什么要学习?直接记忆就好了。这正如同监控录像一眼,如果存储是无限的,而分析查询时间没有限制的,就直接机械录像好了。
  3. 我现在也是先低强度的学习记忆,因为记忆力实在是太差了,只能完全照抄。
  4. 神经网络本身就能够自动组合:
    Deep neural networks exploit the property that many natural signals are compositional hierarchies, in which higher-level features are obtained by composing lower-level ones.

二月二十九日 等待变化等待机会

  1. 休息了两天,一来是俗事,二来换换脑筋。我实在是越来越糊涂,需要重新来纵览一下大图景。偶尔看老电影发现有些下砸的老电影居然已经重新修复成了高清,这个是一个很成熟的领域了。不妨学习一下
  2. 一早上在折腾一个无聊的问题,就是使用webui上传文件如果是nfs的文件夹总是报权限错,最好的解决当然是在nfsserver端创建的uid和我的本地是一样的,可是synology没有usermod,而且新用户都是从1025开始。我很惭愧的是这个基本概念我始终不清楚,为什么我在server的exports里指定了anonuid结果client端反而不能读了。但是这一切瞎折腾的最根本的原因是我想实验upscaler,但是效果不好。人脸变形了,所以,这个实验是没有结果的失败。

三月一日 等待变化等待机会

  1. 关于upscaler的实验暂时告一段落,因为效果并不好,这个的确是有专业成分的,不是随便就可以做好的。
  2. 继续读LeCun2015的论文,这个是一个巡礼式的总结,他提到使用RNN来给CNN来提供标题以便作为训练?至少我是这么理解的,也许机器学习可以形成某种互助关系,取长补短,因为训练材料的收集整理本身就是一个巨大的挑战,在自主学习中这个是至关重要的。他举了一个例子,在这幅图, RNN能够识别出woman throwing frisbee,我使用Interrogate CLIP得到:
    a woman and a child playing frisbee in a field of grass with trees in the background and a river running through the grass, promotional image, Elizabeth Durack, a stock photo, heidelberg school
    似乎更加的详细,如果使用Interrogate DeepBooru得到的更加的详细几乎是驴唇不对马嘴!
    3d, 4girls, audience, aurora, ball, baseball, bicycle, blur censor, blurry, blurry background, blurry foreground, bokeh, building, camera, caution tape, cellphone picture, chain-link fence, christmas tree, chromatic aberration, concert, cosplay photo, day, depth of field, electric fan, fence, field, figure, film grain, focused, garden, glowstick, graffiti, grass, gyaru, gym, hammock, hands on own head, holding ball, holding phone, in the face, jungle, kicking, kogal, leaf, leggings, looking at viewer, male focus, messy hair, motion blur, multiple girls, on grass, outdoors, park, path, people, phone screen, photo \(medium\), photo \(object\), photo background, photo inset, photorealistic, pool, poster \(object\), pov, pov hands, rainbow, recording, reference inset, selfie, shadow, shiny pokemon, shorts, shouji, shrine, sketchbook, soccer, soccer ball, solo focus, sport, stadium, storefront, taking picture, tanaka mamimi, tanzaku, tatami, tennis, throwing, timestamp, tree shade, unconventional media, viewfinder, volleyball

三月三日 等待变化等待机会

  1. 今天偶然看到这个stable-diffusion-2模型决定试一下,发现一直有这个Cannot import ClipProcessor的错误,发现需要先更新transformaers这个模块:
    pip install --upgradie transformers
    pip install --upgradie torch
    
    当然了不要忘记每次都要重新设定tun0的DNS设置,因为我发现Ubuntu似乎会定期刷新这些设置。
  2. 似乎还要安装CUDA驱动

三月五日 等待变化等待机会

  1. 启动笔记本登陆时间无限长。查看journalctl发现启动时候calendar去搜索。这里介绍了三种方法来禁止gnome-software在启动时候就更新,我发现第一种方式我无法修改文件,而且似乎是snap安装的calendar,第二种key似乎也不对。尝试第三种屏蔽packagekit服务:
    
    sudo systemctl mask packagekit.service
    
    等一下重启看看行不行。
  2. 看到类似的错误:
    
    nick@nick-sager:~$ grep --include=*.conf -rnw '/' -e "nvidia-drm" 2>/dev/null
    /etc/modprobe.d/nvidia-graphics-drivers-kms.conf:3:options nvidia-drm modeset=1
    /usr/lib/modprobe.d/nvidia-kms.conf:3:options nvidia-drm modeset=1
    /usr/share/X11/xorg.conf.d/10-nvidia.conf:3:    MatchDriver "nvidia-drm"
    /usr/src/nvidia-550.40.07/dkms.conf:12:BUILT_MODULE_NAME[2]="nvidia-drm"
    
    我尝试禁止了modeset。但是这个是否是黑屏的问题还是延迟的问题,就是说谁是问题,还是都是问题?我看journalctl的时间戳也是不明所以然,似乎都是也都不是。可能昨晚看的时候睡着了吧?
  3. 看到openAI的这个tiktoken,我一开始以为和抖音有关系,其实只是个名字,更主要的是token这个词,不过我对于它声称BPE(Byte Pair Encoding)感觉很神奇:
    1. It's reversible and lossless, so you can convert tokens back into the original text
    2. It works on arbitrary text, even text that is not in the tokeniser's training data
    3. It compresses the text: the token sequence is shorter than the bytes corresponding to the original text. On average, in practice, each token corresponds to about 4 bytes.
    4. It attempts to let the model see common subwords. For instance, "ing" is a common subword in English, so BPE encodings will often split "encoding" into tokens like "encod" and "ing" (instead of e.g. "enc" and "oding"). Because the model will then see the "ing" token again and again in different contexts, it helps models generalise and better understand grammar.
    要编译它需要先安装rust:
    
    sudo apt install rust-all
    pip install .
    
  4. 我无意中看到calendar使用我的gmail创建的一个卷才打开发现在设置里有online account里这个是可以创建一个虚拟的云端的数据盘的,应该是这个问题,我需要把禁止掉,因为没有办法连接到gmail所以才会死等。
  5. eog原本不是原生支持webp格式的,这里说要添加这个包:webp-pixbuf-loader,不过这个已经在ubuntu的官方库里了。
  6. 原本我是想AI可以帮助破解CAPTCHA (Completely Automated Public Turing test to tell Computers and Humans Apart) ,但是这个目前应该是非常的困难的吧? 因为这个目的就是防止机器行为,这个应该是简单的OCR程序难以胜任的。即便训练可能也不行吧?
  7. 如果要学习openAI的库这个是一个入门,可是这个还是让我摸不着头脑,恐怕python的基本常识是我的问题。
  8. 如果需要清理journalctl的log,需要
    
    sudo journalctl --rotate
    sudo journalctl --vacuum-time=1s
    
  9. 我发现geoclue这个服务可能也是一个因素,就把它mask了。此外这个盲人需要的函数xbrlapi我也卸载了。然后启动就飞快了。
  10. 这一次debug长进了不少,就是我发现我的journal居然有将近4G,这个无论如何都是一个隐患,我记得以前遇到过磁盘被耗光的问题。而发现gmail这个云端数据来源无疑是避免了将来的问题,还有geoclue这样子的泄漏行踪的服务都是一些麻烦,不过也许有些网站需要?总而言之,这个比我之前遇到黑屏就认为是nvidia驱动造成的而一股脑卸载驱动要进步的多了。不过nvidia驱动搞坏的问题比这个严重的多,我现在仅仅是desktop不能快速进入的痛苦,而不是彻底黑屏的无奈。
  11. 等我回来就看这个,也许比较适合我目前的状态。还有一个就是CNN包含的内容非常的多,也许很值得学习。毕竟它是现在的Transformer的上一代。

三月七日 等待变化等待机会

  1. 这个总结比我的理解要好的多:
    • ClipText for text encoding.
      Input: text.
      Output: 77 token embeddings vectors, each in 768 dimensions.

    • UNet + Scheduler to gradually process/diffuse information in the information (latent) space.
      Input: text embeddings and a starting multi-dimensional array (structured lists of numbers, also called a tensor) made up of noise.
      Output: A processed information array

    • Autoencoder Decoder that paints the final image using the processed information array.
      Input: The processed information array (dimensions: (4,64,64))
      Output: The resulting image (dimensions: (3, 512, 512) which are (red/green/blue, width, height))

  2. 魔鬼都藏在细节,你从概念上说都理解训练是一个去除噪音的能力的训练,但是具体的过程才是关键,我模模糊糊有一个forward diffusion的名字的印象,但是具体是什么才是最要紧的步骤:
    1. 先是制作训练样品 就是给原始图片依次添加噪音这个过程在我看来是模仿信号传输过程的衰减与人类记忆存储里的自然存储失效的随机过程
    2. 真正训练的是识别图像吗?不!如果是这样子的话,那么和前一代的图像空间的复杂程度岂不是一样了吗?训练的是降噪!因为这个好像是一个大数据量的叠加增量部分,这个δ的数据量小的多! 这里是把事先添加的噪音量作为预测的对象,相当于训练一个降噪器,那么这个和图像的性质似乎是无关,也就是说不同的图片在latent space的数据对于噪音的敏感度也许是更高一阶的函数,往往高维度的信息的函数也要变化率慢于低阶函数吧?这里预测与修正的都是噪音部分,而我们对于图像空间的理解是肤浅的,可是对于噪音空间目前可以说是完全可以先简化为一个标准模型,就是说为什么可以选在常见的正态分布等等,因为磁盘失效,信号衰减在没有人为干预的情况下就是一个标准的随机过程,而且可以简化为白噪音一样。所以,这个预测容易的多!

三月八日 等待变化等待机会

  1. 这一篇论文的数学公式太多了,根本看不懂,我的概率部分太薄弱了,主要是数学表达式方面缺失。
  2. 最主要的问题是我对于正向反向还是搞不明白。当然能够明白核心的巨大进步在引进latent space这个世人皆知的原理也可以满足了吧?
    Now the forward diffusion process is done on the compressed latents. The slices of noise are of noise applied to those latents, not to the pixel image. And so the noise predictor is actually trained to predict noise in the compressed representation (the latent space).
    这个原理图当然是容易理解的,可是具体步骤却依然不甚了了 这幅图是怎么和这个反复看到的流程图联系起来的呢?我以为最最核心的也是最最复杂的细节就是在这里 因为其他部分都是普通人都能理解的原理部分,而所有的改进与数学算法就在这个核心部分,而恰恰是这个核心部分看不懂!论文里的数学部分太多了,而这个仅仅是一个部分,更主要的是训练是一个逆过程,当你把大部分的数据进行了有损压缩之后再还原的时候肯定是要有很多假设条件的吧?应该是训练的时候有些假设条件啊,作者似乎是说有些参数是不可能学习的,究竟正态分布高斯噪音的哪些参数是不可能学习的?这个依据是什么?是不可能还是理想化? 其实正太分布和高斯分布是一回事。
  3. Their importance is partly due to the central limit theorem. It states that, under some conditions, the average of many samples (observations) of a random variable with finite mean and variance is itself a random variable—whose distribution converges to a normal distribution as the number of samples increases. Therefore, physical quantities that are expected to be the sum of many independent processes, such as measurement errors, often have distributions that are nearly normal.
    其实我需要熟记得是标准的正态分布
    The simplest case of a normal distribution is known as the standard normal distribution or unit normal distribution. This is a special case when μ = 0 and σ = 1, and it is described by this probability density function (or density): φ ( z ) = e - z 2 / 2
    我现在可以熟练的使用mathtml这个本身是一个加深对于公式记忆的好方法。 我似乎发现了一个wiki的笔误,就是高斯分布是标准正态分布的一个变形,那是当σ(variance)的平方等于½而不是σ本身: σ = 1 2 只有这样子才是高斯分布 φ ( z ) = e - z 2 π 到这里我们可以明白其实如果假定分布符合正太分布,那么核心就是发现σ或者说variance。明白了这一点就好理解多了,至于说Markov链的前件后件之类的概念我感觉就是纯粹的数学计算吧?这个我不确定,不过今天的学习到此为止了。

三月九日 等待变化等待机会

  1. 其实从最最基本的训练入手得到的是最直观的感觉。这个word2vector的深入浅出的讲解是非常的好的。细节就在于最简单的概念之后,在我买完油条后再来看吧。这个好像就是所谓的N-gram
  2. 这里是word2vector的论文这个是改进最根本的源头是另一篇。看论文还是有些吃力尽管这篇论文相对来说比较容易,但是问题是我对于几个架构的细节不清楚,所以一到复杂度分析部分就不知所以然了。不过这个是否是我需要目前理解的细节呢?不如还是从论文讲解的这种博客入手。
  3. 这篇博客提到的这篇去噪音的论文我一看就头疼,权且下载吧。
  4. 这篇博客有一个好的地方是引文都有下载链接这篇论文《A Neural Probabilistic Language Model》这篇论文的好处是它给出了一个训练算法的细节也许学习这个过程是很有意义的?似乎是这个领域的最先的先驱?我看明白了大部分,应该说绝大部分人都能看的懂的部分,但是到了关键的实现细节的解说我就迷糊了,作者的视频并没有什么帮助,因为基本上都是概述而已。不过他的频道倒是可以作为平常泛泛浏览。
    这个是它的频道视频

三月十日 等待变化等待机会

  1. 为什么是语言大模型?没有想过这个问题的肯定是不够资格的:
    Language models have a huge advantage over most other machine learning models. That advantage is that we are able to train them on running text – which we have an abundance of. Think of all the books, articles, Wikipedia content, and other forms of text data we have lying around. Contrast this with a lot of other machine learning models which need hand-crafted features and specially-collected data.
  2. 其实,这些都是最最基本的常识,我没有想过那说明我没有这个基础。首先就是理解 joint distribution
    A joint distribution is a probability distribution having two or more independent random variables. In a joint distribution, each random variable will still have its own probability distribution, expected value, variance, and standard deviation. In addition, probabilities will exist for ordered pair values of the random variables. Furthermore, the strength of any relationship between the two variables can be measured.
    而作为joint distribution的两个随机变量这个是基本的公式: 我喜欢这个标准化的公式的一个原因是作者有现成的mathtml代码:
    Suppose a joint distribution of the random variables X and Y are given in table form, so that PXY(X=x,Y=y), typically abbreviated as PXY(x,y), is given for each pair (x,y), of random variables. As with all discrete distributions, two requirements must hold for each pair (x,y): 0 P X Y ( x , y ) 1 all  x all  y P X Y ( x , y ) = 1
    而这个所谓的marginal probabilities我一开始被吓了一跳,后来才回想起这个是很普通的概念:
    Then the marginal probabilities PX(X=x) and PY(Y=y), the expected values E(X) and E(Y), and the variances Var(X) and Var(Y) can be found by the following formulas. P X ( X = x ) = all  y P X Y ( x , y ) P Y ( Y = y ) = all  x P X Y ( x , y ) E ( X ) = all  x x P X ( x ) E ( Y ) = all  y y P Y ( y ) V a r ( X ) = all  x x 2 P X ( x ) ( E ( X ) ) 2 V a r ( Y ) = all  y y 2 P Y ( y ) ( E ( Y ) ) 2
    之所以重温这个概念是因为这篇很重要的论文要解决的所谓的curse of dimensionality,而这个核心的难题curse of dimensionality就在于要把一组词作为一个joint distribution来训练的天文数字的组合:
    For example, if one wants to model the joint distribution of 10 consecutive words in a natural language with a vocabulary V of size 100,000, there are potentially 10000010 − 1 = 1050 − 1 free parameters.
    这个就是基本的问题,如果没有理解问题根本谈不上寻找解决问题的方法!
  3. 很多基础的概念我没有学习过,比如这个non-parametric density estimation
    The models we saw in the previous chapters share a common root: all of them are parametric. This means that they assume a certain structure on the regression function m, which is controlled by parameters185. If this assumption truly holds, then parametric methods are the best approach for estimating m. But in practice it is rarely the case where parametric methods work out-of-the-box, and several tricks are needed in order to expand their degree of flexibility in a case-by-case basis. Avoiding this nuisance is the strongest point of nonparametric methods: they do not assume major hard-to-satisfy hypotheses on the regression function, but just minimal assumptions, which makes them directly employable. Their weak points are that they usually are more computationally demanding and are harder to interpret.
    这个是一个概率推理的范畴,我之前基础很薄弱。具体的公式开头看明白了,后面就丢了,就比如这个density的问题,本来以为很简单,但是只看懂了开头。
  4. 但是至少今天我明白了几个基本的概念,或者说动机:为什么是语言大模型?因为训练材料的充足容易,所以,它是最最基本的入手。而之前我们理解了为什么是多个大模型联动?这是另一个机器学习的微妙之处,这个可以看作自主学习的一个基本能力:transduct可以不用在训练中实际出现过,那么推而广之,训练图像识别是否是否可以从文字识别的高成功率来推动?一个强大的语言模型最后联合一个普通的图像标题模型训练居然成为更高准确率的方式,这些都是革命性的。而这篇论文的核心要解决的是这个curse of dimentionality难道不会出现在别的领域吗?作者的思路是什么?不是简单的N-gram的机械的有序词组n-grams with n up to 5 (i.e. 4 words of context) have been reported, though, but due to data scarcity, most predictions are made with a much shorter context.(这个是作者指出的问题实质:N-gram其实没有普遍性,四字成语不是大多数语言的特征),那是什么?前人的工作缺陷在哪里?
    First, it is not taking into account contexts farther than 1 or 2 words, second it is not taking into account the “similarity” between words.
    对,就是不能机械的固定几个N-gram,而且要考虑相似性,也就是要能够触类旁通,举一反三。但是这个是多么的难啊,如果自主学习做得到我们还发愁吗?
  5. 作者说这个是他们的核心思想:
    1. associate with each word in the vocabulary a distributed word feature vector (a real-valued vector in Rm),
    2. express the joint probability function of word sequences in terms of the feature vectors of these words in the sequence, and
    3. learn simultaneously the word feature vectors and the parameters of that probability function.
    我的理解就是这里的word feature vector就是现在人们常说的embedding吧?这里是作者的核心思想解释:
    The feature vector represents different aspects of the word: each word is associated with a point in a vector space. The number of features (e.g. m =30, 60 or 100 in the experiments) is much smaller than the size of the vocabulary (e.g. 17,000).
    这个是两个思考方式的碰撞:通常人们把一组词看作是一个有机的整体,比如一个有十万词汇的词库里每十个有序词组就是一个整体,可是现实中有那么多吗?中文的四字成语也许是它的例证,可是大多数语言里没有这个整齐划一的结构实体,反而是硬性的机械的这个处理方式出现了难以克服的维度诅咒;那么换种思考,也许确实有这个潜在的实体,可是能不能把这个十个词扩展到三十,五十?不敢,因为十个就很大了何况三十五十?而这里就是出彩的思考,就是每一个词也许都有这么一个出现在几十个词的上下文的属性,那么用什么来表达呢?太具体的不一定有,可以用向量来表达,其实有的词很活跃,它说不定三十个维度还不够,可是很多词三十个维度绰绰有余,但是不管怎么样,我们得到了一个统一。这个计算空间立刻从指数级降低到了线性的空间了。这个真的是高明。
  6. 我有大量的概率论知识要温习与学习,有一些是熟知的但是名词不熟悉的,比如这个难道不就是通常所理解的条件概率吗?

三月十一日 等待变化等待机会

  1. probability mass function其实很简单在于:
    A probability mass function differs from a probability density function (PDF) in that the latter is associated with continuous rather than discrete random variables. A PDF must be integrated over an interval to yield a probability.
    仅仅因为它是离散的概率密度函数而已。而使用Log Likelihood Function的原因是因为我们可以把乘法变加法,其次画图也更容易一些。
  2. 这是关于likelihood statistics的讲稿,学习一下是很有意义的。
  3. 我现在回过头来温习我的笔记感觉大有裨益,首先是很多的概念定义的摘抄是非常值得的,因为概念往往需要反复阅读与理解,一次两次多次,很多时候即便是理解了也会忘记需要反复加深记忆。其次,很多概念是融会贯通才能真正领会,尤其是很多概念实际上是建立其他更复杂概念的基石,你学习这些基本概念的目的是为了学习掌握更复杂更高级概念的必由之路,所以,有时候在当时是仅仅能够掌握基本概念而无瑕真正集中注意力在当前的高级概念,顾此失彼,模模糊糊,而复习的过程是一个真正的好整以暇融会贯通的机会。更何况很多提纲挈领只有在扫清了外围据点之后发起的总攻才能发现,而这个总攻过程往往又会再次发现很多以前没有攻击到跟前而看不到的隐蔽火力点。这个突击过程往往不是一蹴而就,反复拉锯是不能避免的。在这种反复拉锯过程中往往很多之前在另外一个方向的疑团也能触类旁通式的理解了,这个本身就是一个学习过程,与其说机器学习是一个模仿人类学习的过程还不如说它是一个精炼科学化系统化规律化的过程,学习过程本身就是有一个客观规律的性质,只不过在人类自己无法概念化之前把它神话为某种智慧生物特有的过程而已,哪有什么独一无二?只不过没有见过就以为世间独有!人类掌握机器学习的过程就是人类自我解放的过程,它的最终也许是人类自身的替代结局,但是对于整个文明一定是一次跨越式的革命演化。站在整个宇宙文明的角度来看人类自我革命是一个自然而不可阻挡的必然进程,一切企图阻挡历史车轮前进的螳臂挡车必然是被历史的车轮碾为齑粉!

三月十二日 等待变化等待机会

  1. 有很多深奥的理论是需要在以后深入学习中才能理解,比如这里
    ... the probability function is a smooth function of these feature values, a small change in the features will induce a small change in the probability.
    作者是在这里解释为什么相似的字词能够获益于其算法。可是在我看来这个是很深奥的概率理论。比如阅读这个讲演是很有长进的: i = 1 n 1 2 π exp 就比如这里的是数学上的连乘的符号,而不能简单的用π来代表。至少不好看。其实我内心是理解了likelihood function的只是嘴上说不出,它本身不能看作是概率分布,但是它是相关的,因为是看作在一个带参数的概率分布观察到的实际的随机变量的值之后人们用来推测的这些值再次发生的一个可能性,这个似乎也是字面的理解,可能性和概率在中文有什么不同呢?这个不是数学语言。
    The likelihood function is not a probability distribution.
    • It does not transform like a probability distribution.
    • Normalization is not defined.
    可是这些空洞的概念对于我有什么意义呢?我觉得我会用到的是求它的最大值的log,后者是因为取对数转化为加法可以简化计算量,前者是因为研究正态分布时候倒退它的参数在最大值点可以得到mean。
  2. 这里再强调一下这个w3的mathml的核心入口
  3. 这里是真正的Likelihood function的定义
    The likelihood function (often simply called the likelihood) is the joint probability mass (or probability density) of observed data viewed as a function of the parameters of a statistical model. Intuitively, the likelihood function L ( θ x ) is the probability of observing data x assuming θ is the actual parameter.
    这里要注意的是在统计学里parameter是有独特含义的,说白了就是关于随机过程的mean和standard deviation。因为研究一个概率模型最基本的就是这两样东西,它们描述了一个模型的基本样貌。而这里的概率模型其实反而是一个更加虚拟的假设,是一个数学的假设公式化的推测。那么人们在模型未建立之前的观察得到的实际数据成为一种经验值来作为推测的随机过程再次发生的可能性,这就是这个likelihood function的本意。
  4. 之所以我们关心Maximum likelihood estimation是因为我们研究的目的就是要试图建立概率模型,而最基本的就是它的参数,因为基本上不管什么样的模型,几乎必然的它的最大值都在它的mean的附近或者就是重合的,我实在想不出是否不重合的可能性?这个当然是不重合了,这个仅仅是正态分布的特例。只不过AI的噪音模型大多数都是假定为normal distribution而已。maximum被称作mode,大概是吧?
    In statistics, maximum likelihood estimation (MLE) is a method of estimating the parameters of an assumed probability distribution, given some observed data. This is achieved by maximizing a likelihood function so that, under the assumed statistical model, the observed data is most probable. The point in the parameter space that maximizes the likelihood function is called the maximum likelihood estimate. The logic of maximum likelihood is both intuitive and flexible, and as such the method has become a dominant means of statistical inference.
    这里是多么清楚的解释和定义啊!一目了然的,根本不需要多余的话!它就是一种inference,而且是做了很合理的假设。
  5. 在学习了这些基础知识后我们再来读这段话
    The probability function is expressed as a product of conditional probabilities of the next word given the previous ones, (e.g. using a multilayer neural network to predict the next word given the previous ones, in the experiments). This function has parameters that can be iteratively tuned in order to maximize the log-likelihood of the training data or a regularized criterion, e.g. by adding a weight decay penalty. The feature vectors associated with each word are learned, but they could be initialized using prior knowledge of semantic features.
    这段文字可谓是字字珠玑,它描述了整个过程,说到底这个Markov链它就是一个条件概率的结果,所以,我们所谓的预测下一个字就是当初观察到的实际发生的随机变量实际值来倒推概率模型,而反复微调迭代取得概率最大值实际上也是在摸索寻找假设的概率模型的参数,因为我们已经假设了正态分布。这里weight decay penalty作者的注解是Like in ridge regression, the squared norm of the parameters is penalized. 这里又要补课:
    Ridge regression is a statistical regularization technique. It corrects for overfitting on training data in machine learning models.

    Ridge regression—also known as L2 regularization—is one of several types of regularization for linear regression models. Regularization is a statistical method to reduce errors caused by overfitting on training data. Ridge regression specifically corrects for multicollinearity in regression analysis. This is useful when developing machine learning models that have a large number of parameters, particularly if those parameters also have high weights.

    这里提到的multicollinearity指的是
    Multicollinearity denotes when independent variables in a linear regression equation are correlated. Multicollinear variables can negatively affect model predictions on unseen data. Several regularization techniques can detect and fix multicollinearity.
    我感觉这个就是自相矛盾的,因为我印象中所谓的independent variable本来就是彼此的发生概率是独立不受影响的,而说它们是correlated就是自定义的错误,当然也许是我们现实中理想的独立并不实际存在,只是影响因素可以忽略而已吧?看来我把概念混淆了,这里的independent和dependen variable并不是独立概率里的Independent Random Variables的概念
    In the simple stochastic linear model

    yi = a + bxi + ei

    the term yi is the ith value of the dependent variable and xi is the ith value of the independent variable. The term ei is known as the "error" and contains the variability of the dependent variable not explained by the independent variable.
    这个概念其实是更加泛泛的数学概念
  6. 再补课linear regression model
    A linear regression model describes the relationship between a dependent variable, y, and one or more independent variables, X. The dependent variable is also called the response variable. Independent variables are also called explanatory or predictor variables. Continuous predictor variables are also called covariates, and categorical predictor variables are also called factors. The matrix X of observations on predictor variables is usually called the design matrix.

    A multiple linear regression model is

    yi01Xi12Xi2+⋯+βpXipi, i=1,⋯,n,

    where
    • n is the number of observations.
    • yi is the ith response.
    • βk is the kth coefficient, where β0 is the constant term in the model. Sometimes, design matrices might include information about the constant term. However, fitlm or stepwiselm by default includes a constant term in the model, so you must not enter a column of 1s into your design matrix X.
    • Xij is the ith observation on the jth predictor variable, j = 1, ..., p.
    • εi is the ith noise term, that is, random error.
  7. 这篇论文读的好辛苦啊,几乎每一个字都是需要补课,我看引言就看了两三天。不过我觉得是值得的,因为它是几乎所有的基础,尤其是背后的统计学的理论基础是必不可少的。只是要消化吸收还需要很多时间和反复。
  8. 这里有一个中西方的语言的误导,或许是我自己没有概念,这里的Regression是有一个统计学上的特定含义的:
    Regression analysis, a statistical technique for estimating the relationships among variables. There are several types of regression:
    看了这些我才有些开窍,现实世界里我们从现象来推测事物运行的本质规律就是一个归纳的过程,有些时候我们为了简化或者我们已经有证据支持某些模型,所以,我们可以用很少的实验数据来勾勒出概率模型公式。与此相对的是Nonparametric
    Nonparametric regression is a category of regression analysis in which the predictor does not take a predetermined form but is constructed according to information derived from the data. That is, no parametric form is assumed for the relationship between predictors and dependent variable. Nonparametric regression requires larger sample sizes than regression based on parametric models because the data must supply the model structure as well as the model estimates.
    这里的不完全列表把我都看吐了。
  9. 感觉太累了。休息吧。我想去大自然里奔跑!

三月十三日 等待变化等待机会

  1. 我现在开始明白所谓的线性回归(Linear Regression)是一个非常复杂的课题,其中有大量的概念与理论要学习,而它背后的这些根本原因其实是更加的深奥,而这一切都是基于很多的关于一个观察的现象中假定有多少个独立变量,有多少个依赖变量,而它们直接的关系又是如何,这个简直就像是要靠单单的观察一个复杂的多齿轮精密的钟表来推理它的齿轮间转动规律一般。单单学习这个领域就可能穷尽一个人的一生,因为这个彷佛是一个数学的逆向工程,大自然写了一个复杂的函数然后把这个函数作为概率密度函数让你依靠仍色子来猜出这个函数,这个简直就是在破解上帝设置的大自然的密码!
  2. 我的线性代数是白学了因为我居然不知道Eigenvalue和EigenVector的数学含义!
    In linear algebra, it is often important to know which vectors have their directions unchanged by a given linear transformation. An eigenvector (/ˈaɪɡən-/ EYE-gən-) or characteristic vector is such a vector. Thus an eigenvector v of a linear transformation T is scaled by a constant factor λ when the linear transformation is applied to it: T v = λ v. The corresponding eigenvalue, characteristic value, or characteristic root is the multiplying factor λ.
    而它的几何意义其实更加的有用和直观
    Geometrically, vectors are multi-dimensional quantities with magnitude and direction, often pictured as arrows. A linear transformation rotates, stretches, or shears the vectors upon which it acts. Its eigenvectors are those vectors that are only stretched, with no rotation or shear. The corresponding eigenvalue is the factor by which an eigenvector is stretched or squished. If the eigenvalue is negative, the eigenvector's direction is reversed.
    很显然的这个对于线性变换肯定是非常的有针对性的意义的特殊指向,简直就是线性变换的变换方向,由此而知其发力的方向,那么它的意义能不大吗?它的数学表达是这样子的:
    If T is a linear transformation from a vector space V over a field F into itself and v is a nonzero vector in V, then v is an eigenvector of T if T(v) is a scalar multiple of v. This can be written as

    T ( v ) = λ v , (in Matrix language, it is Au = λu where A is the matrix representation of T and u is the coordinate vector of v. )

    where λ is a scalar in F, known as the eigenvalue, characteristic value, or characteristic root associated with v.
  3. 结果就是我才意识到之所以统计和线性代数有这么密切的关系是因为大量的统计学的公式往往是大量的观察数据的结果,而要找出其规律又要求助于线性变换的大量的应用,所以,线性代数是一个具体的数学工具是统计数据抽象化的数学结果以及如何通过结果寻找规律的手段。结果就是我又发现线性代数的基础又要重新温习学习,很多概念或者忘记了,或者根本没有接触过。
  4. 一个矩阵的是什么几何意义呢?我似乎完全没有印象!居然是两个向量组成的平行四边形的面积!作为三维向量那就是体积了。代数在几何空间的意义往往是更加的直观与重大。
  5. 我似乎完全忘记了这个kernel的定义。
  6. 补课补的头疼啊。
  7. 我把向量的叉乘和外乘搞混了。cross product依旧是一个向量是和相乘的两个向量垂直的法线向量。现在回过头来看实际上和线性回归大有渊源你可以看作是一组dependent variable对于一个线性方程关系的n次的实验,因为这个变量是这个线性关系的n次的系数。

三月十四日 等待变化等待机会

  1. 学习必要的基础数学告一段落,因为我的目的还是读这篇论文,而基础永远是不够的,够用就好,而且我目前仅仅是帮助理解,远没有到实现级别的细节。所以,回过头来看
    The idea of using neural networks for language modeling is not new either (e.g. Miikkulainen and Dyer, 1991). In contrast, here we push this idea to a large scale, and concentrate on learning a statistical model of the distribution of word sequences, rather than learning the role of words in a sentence.
    这段话其实很关键,作者有划重点,我认为这肯定是作者要强调的核心思想。在肯定前人的成就基础上的,并不是完全的新思想,只是把前人的想法放大。但是也有创新的,就是这个我还没有理解的是distribution of word sequences,那么什么是role of words in a sentence?这个要好好体会。而前人的思想是each word is associated deterministically or probabilistically with a discrete class, and words in the same class are similar in some respect.作者的不同在于:
    In the model proposed here, instead of characterizing the similarity with a discrete random or deterministic variable (which corresponds to a soft or hard partition of the set of words), we use a continuous real-vector for each word, i.e. a learned distributed feature vector, to represent similarity between words.
    这篇论文的核心要点就是这里learned distributed feature vector。我们要搞明白的它是什么,它为什么可以,要怎么做。
  2. 向量空间来表达也不是什么新鲜主意,但是作者强调他们的创新是
    An important difference is that here we look for a representation for words that is helpful in representing compactly the probability distribution of word sequences from natural language text.
    所以,我们要理解这里的表达不是单个词而是一组词,这个和N-gram要取得的效果目的是类似的,但是是聪明的解脱了维度诅咒(curse of dimentionality)的一个好方法,把一个词库里几何级数的组合概率改为了某种线性的一维,代价是每一个单词是有远远大于通常人们做N-gram的维度,据我所知只有不到5维。这个就是一个非常的强悍的地方。因为对于词组这样子的有序序列实际上也是很难的一个模型,大量的语言现象其实是无序的,或者说是不值得有序,汉语中四字一组的成语是大多数语言中罕见的,那么结果就是要构造常用词组的模型是非常困难或者说模糊的,我想这里的向量空间是一个足够模糊的方式,甚至于好像人类DNA序列一样的看起来模糊的。这个比喻似乎很不恰当,DNA也许像程序代码一样的有特殊含义,可是人类自然语言似乎没有那么严格的语法。
  3. 这里的一处细节我始终没有理解:
    Experiments suggest that learning jointly the representation (word features) and the model is very useful.
    这里的一鱼两吃是什么意思?到底学的是什么?建立的是什么?这个是理解的真正核心,我能回答这个问题这篇论文才算理解了。作者接下来的描述我同样的不理解
    We tried (unsuccessfully) using as fixed word features for each word w the first principal components of the co-occurrence frequencies of w with the words occurring in text around the occurrence of w.
    为什么是unsuccessfully?难道这个是另一个方向的尝试?我曾经预想过fixed word features不大可能,那么不是fixed,哪能怎么办?还能是动态的?或者意思是我的英文理解有问题,这里指的是单词相对于上下文的不同而不同?那这个和N-gram有什么区别?我越看越糊涂了。
  4. 最终语言的描述是受限于读者如我一样的理解能力,尤其是第二语言更是如此,只有数学语言才是精确的,所以,这个摘抄是非常非常必要的理解过程:
    The training set is a sequence w1 · · · wT of words wt ∈ V , where the vocabulary V is a large but finite set. The objective is to learn a good model f ( w t ,..., w t−n+1 ) = P ˆ ( w t | w t-1 1 ) , in the sense that it gives high out-of-sample likelihood. Below, we report the geometric average of 1 P ˆ ( w t | w t-1 1 ) , also known as perplexity, which is also the exponential of the average negative log-likelihood
    这里先科普一下perplexity
    In information theory, perplexity is a measure of uncertainty in the value of a sample from a discrete probability distribution. The larger the perplexity, the less likely it is that an observer can guess the value which will be drawn from the distribution.
    简而言之就是复杂度或者难易程度,如果一个考公务员的特殊试卷只有对和错两个选择,那么白痴也能得的满分几率几乎就是50%,这个让一个白痴AI去随机猜对的可能是很大的,算不得本事。只有选择空间很大才方显英雄本色。
  5. 这里补习一下各种数学符号
    Symbol Name Date of earliest use First author to use
    horizontal bar for division 14th century (approx.) Nicole Oresme
    +
    plus sign 1360 (approx.), abbreviation for Latin et resembling the plus sign Nicole Oresme
    minus sign 1489 (first appearance of minus sign, and also first appearance of plus sign in print) Johannes Widmann
    radical symbol (for square root) 1525 (without the vinculum above the radicand) Christoff Rudolff
    (...)
    parentheses (for precedence grouping) 1544 (in handwritten notes) Michael Stifel
    (...)
    parentheses (for precedence grouping) 1556 Niccolò Tartaglia
    =
    equals sign 1557 Robert Recorde
    .
    decimal separator 1593 Christopher Clavius
    ×
    multiplication sign 1618 William Oughtred
    ±
    plus–minus sign 1628 William Oughtred
    proportion sign 1628 William Oughtred
    x n
    radical symbol (for nth root) 1629 Albert Girard
    <
    >
    strict inequality signs (less-than sign and greater-than sign) 1631 Thomas Harriot
    xy
     
    superscript notation (for exponentiation) 1636 (using Roman numerals as superscripts) James Hume
    x
     
    Use of the letter x for an independent variable or unknown value. See History of algebra: The symbol x. 1637[2] René Descartes (La Géométrie)
    xy
     
    superscript notation (for exponentiation) 1637 (in the modern form) René Descartes (La Géométrie)
    √ ̅
    radical symbol (for square root) 1637 (with the vinculum above the radicand) René Descartes (La Géométrie)
    %
    percent sign 1650 (approx.) unknown
    infinity sign 1655 John Wallis
    ÷
    division sign (a repurposed obelus variant) 1659 Johann Rahn


    unstrict inequality signs (less-than or equals to sign and greater-than or equals to sign) 1670 (with the horizontal bar over the inequality sign, rather than below it) John Wallis
    integral sign 1675 Gottfried Leibniz
    d
    differential sign 1675 Gottfried Leibniz
    :
    colon (for division) 1684 (deriving from use of colon to denote fractions, dating back to 1633) Gottfried Leibniz
    ·
    middle dot (for multiplication) 1698 (perhaps deriving from a much earlier use of middle dot to separate juxtaposed numbers) Gottfried Leibniz
    division slash (a.k.a. solidus) 1718 (deriving from horizontal fraction bar, invented by Abu Bakr al-Hassar in the 12th century) Thomas Twining


    unstrict inequality signs (less-than or equals to sign and greater-than or equals to sign) 1734 (with double horizontal bar below the inequality sign) Pierre Bouguer
    x
    prime symbol (for derivative) 1748 Leonhard Euler
    Σ
    summation symbol 1755 Leonhard Euler
    proportionality sign 1768 William Emerson
    partial differential sign (a.k.a. curly d or Jacobi's delta) 1770 Marquis de Condorcet
    identity sign (for congruence relation) 1801 (first appearance in print; used previously in personal writings of Gauss) Carl Friedrich Gauss
    !
    factorial 1808 Christian Kramp
    [x]
    integral part (a.k.a. floor) 1808 Carl Friedrich Gauss
    Π
    product symbol 1812 Carl Friedrich Gauss

    set inclusion signs (subset of, superset of) 1817 Joseph Gergonne
    |...|
    absolute value notation 1841 Karl Weierstrass
    |...|
    determinant of a matrix 1841 Arthur Cayley
    ‖...‖
    matrix notation 1843[3] Arthur Cayley
    nabla symbol (for vector differential) 1846 (previously used by Hamilton as a general-purpose operator sign) William Rowan Hamilton

    intersection

    union
    1888 Giuseppe Peano

    set inclusion signs (subset of, superset of) 1890 Ernst Schröder
    aleph symbol (for transfinite cardinal numbers) 1893 Georg Cantor
    membership sign (is an element of) 1894 Giuseppe Peano
    O
    Big O Notation 1894 Paul Bachmann
    {...}
    braces, a.k.a. curly brackets (for set notation) 1895 Georg Cantor
    Blackboard bold capital N (for natural numbers set) 1895 Giuseppe Peano
    Blackboard bold capital Q (for rational numbers set) 1895 Giuseppe Peano
    existential quantifier (there exists) 1897 Giuseppe Peano
    ·
    middle dot (for dot product) 1902 J. Willard Gibbs
    ×
    multiplication sign (for cross product) 1902 J. Willard Gibbs
    logical disjunction (a.k.a. OR) 1906 Bertrand Russell
    (...)
    matrix notation 1909[3] Maxime Bôcher
    [...]
     
    matrix notation 1909[3] Gerhard Kowalewski
    contour integral sign 1917 Arnold Sommerfeld
    Blackboard bold capital Z (for integer numbers set) 1930 Edmund Landau
    universal quantifier (for all) 1935 Gerhard Gentzen
    arrow (for function notation) 1936 (to denote images of specific elements) Øystein Ore
    empty set sign 1939 André Weil / Nicolas Bourbaki[4]
    Blackboard bold capital C (for complex numbers set) 1939 Nathan Jacobson
    arrow (for function notation) 1940 (in the present form of f: XY) Witold Hurewicz
    end of proof sign (a.k.a. tombstone) 1950[5] Paul Halmos
    x x
    greatest integer ≤x (a.k.a. floor)

    smallest integer ≥x (a.k.a. ceiling)
    1962[6] Kenneth E. Iverson
    inequality sign (not equal to) unknown Leonhard Euler
    然后我发现这个表的数学符号更全一些。而我为了找这个Hat notation花了差不多一个小时,我印象中学校里经常用,但是就是叫不出名字来:而这个是在统计学里有特定含义的,不同于以前逻辑或者其他领域的含义。
    In statistics, a circumflex (ˆ), called a "hat", is used to denote an estimator or an estimated value. For example, in the context of errors and residuals, the "hat" over the letter ε ^ indicates an observable estimate (the residuals) of an unobservable quantity called ε (the statistical errors).
  6. 在统计学里这个概念是相当的重要,因为我觉得直觉是不足以意识到这个概念,就是说它们是两个不同的概念,但是又是紧密相联系的:
    In statistics and optimization, errors and residuals are two closely related and easily confused measures of the deviation of an observed value of an element of a statistical sample from its "true value" (not necessarily observable). The error of an observation is the deviation of the observed value from the true value of a quantity of interest (for example, a population mean). The residual is the difference between the observed value and the estimated value of the quantity of interest (for example, a sample mean). The distinction is most important in regression analysis, where the concepts are sometimes called the regression errors and regression residuals and where they lead to the concept of studentized residuals. In econometrics, "errors" are also called disturbances.
    都是偏差可是原因不同。这个是中文的名词对照:误差(error)和残差(residual)。 而Population Mean在中文里叫做总体平均值,相对应的Sample Mean叫做样本平均值。这些在中文里意思似乎很清楚,但是会误导。它们真正的数学或者说统计学上的意义是深奥的。
    In statistical inference, a subset of the population (a statistical sample) is chosen to represent the population in a statistical analysis. Moreover, the statistical sample must be unbiased and accurately model the population (every unit of the population has an equal chance of selection). The ratio of the size of this statistical sample to the size of the population is called a sampling fraction. It is then possible to estimate the population parameters using the appropriate sample statistics.
    这个是statistical inference的基本出发点,而这些概念也许在descriptive statistic的角度来看就是官僚主义的正常节奏,可是在推本逐源的探索过程就是大学问。
    A statistical error (or disturbance) is the amount by which an observation differs from its expected value, the latter being based on the whole population from which the statistical unit was chosen randomly.
    而与之相对的是
    A residual (or fitting deviation), on the other hand, is an observable estimate of the unobservable statistical error.
    看起来两者的来源是截然不同的。前者是不可避免的因为你的取样总是小于总体样本,如果不是的话根本就不用研究统计学直接去暴力调查所有样本就可以了吗?统计学就是要少花钱多办事才对,见微知卓,管中窥豹。所以,这个是不可避免的,除非是理想的概率分布严格的发生,可是上帝会掷色子吗?上帝的色子是绝对均匀的吗?即便是,我们能够有幸在少数样本里正好得到准确的概率分布的样本吗?

    后者是有些主观因素在起作用,能否观察到是一个问题,选取合适的样本也是一个问题,就是人为去除噪音这个需要人的信念支持,或者说有主观成分了。

    The sample mean is the average of the values of a variable in a sample, which is the sum of those values divided by the number of values.

    总而言之,两者非常的相似,甚至在实际工作中是一回事,但是理论上能否避免则有不同,前者是不可能,后者是可能。
  7. 为什么要花这么多时间来理解这些枯燥的东西呢?原因是人工智能说到底是依靠statistical inference的方法和理论来探索其概率分布来作为模型以便应用。那么这个探索的方法和过程就是大有学问了。
  8. 归根结底是这个神经网络的模型的数学表达式的准确理解是什么?这里的下标突然冒出一个未定义的n,那么是不是说 f ( w t ,..., w t - n + 1 ) = P ˆ ( w t | w t-1 1 ) 这里的n是当前context下n个单词的词组概率?总之,我的理解是这里的n不是一个变量而是一个常量。在接下去注意这个细节。而这里接下去都是硬核,完全是最最至关重要的定义与实现细节。我感觉今天已经疲乏了,明日再战。
  9. 这个是最复杂的部分,先从模型定义的公式开始:这里是所有的拉丁字母在数学上的应用
    We decompose the function f ( w t ,..., w t - n + 1 ) = P ˆ ( w t | w t-1 1 ) in two parts:
    1. A mapping C from any element i of V to a real vector C(i) ∈ ℝm. It represents the distributed feature vectors associated with each word in the vocabulary. In practice, C is represented by a|V| × m matrix of free parameters.
    2. The probability function over words, expressed with C: a function g maps an input sequence of feature vectors for words in context, (C(wt−n+1), ...,C(wt−1)), to a conditional probability distribution over words in V for the next word wt . The output of g is a vector whose i-th element estimates the probability P ˆ ( w t | w t-1 1 ) as in Figure 1.

      f (i, wt−1, ... , wt−n+1) = g(i,C(wt−1), ...,C(wt−n+1))

    我先把定义抄了一遍,文字部分还比较清楚,但是这个架构图就非常的复杂,需要花至少一两天来理解。

三月十五日 等待变化等待机会

  1. 有大量的数学基础要补习,比如对于group我原来是有概念的,只是忘记了,要温习一下。
    A group is a non-empty set G together with a binary operation on G, here denoted " ⋅ ", that combines any two elements a and b of G to form an element of G , denoted a ⋅ b, such that the following three requirements, known as group axioms, are satisfied:
    • Associativity

      For all a , b, c in G , one has ( a ⋅ b ) ⋅ c = a ⋅ ( b ⋅ c ) .
    • Identity element

      There exists an element e in G such that, for every a in G , one has e ⋅ a = a and a ⋅ e = a . Such an element is unique. It is called the identity element (or sometimes neutral element) of the group.
    • Inverse element

      For each a in G , there exists an element b in G such that a ⋅ b = e and b ⋅ a = e , where e is the identity element. For each a , the element b is unique; it is called the inverse of a and is commonly denoted a-1 .
  2. 数学上有一个metric space的概念:
    In mathematics, a metric space is a set together with a notion of distance between its elements, usually called points. The distance is measured by a function called a metric or distance function.
    为什么我们需要这个概念呢?原因是我们需要distance-preserving transformation的概念,这个是线性变换的一个特殊变换,它的严格的数学定义是显而易见的:这里有一个小的技巧我花了快一个小时才找到,就是数学上定义集合的blackboard bold字体我不想使用unicode就是用mathvariant来定义字体,这里使用Double-struck就可以取得这个效果。
    Let X and Y be metric spaces with metrics (e.g., distances) dX and dY . A map f:XY is called an isometry or distance preserving map if for any a,bX one has d X ( a , b ) = d Y ( f ( a ) , f ( b ) )
  3. 这里是数学的所谓的BlackBoard Bold的html表达,有时候你都不知道要怎么去搜索这些东西。
  4. 这个网站的数学符号比较全
    MathML Symbol HTML Entity Hex Code Description
    - &minus; &#x2212; To specify subtraction
    × &times; &#x00d7; To specify multiplication
    ÷ &divide; &#x00f7; To specify division
    &ne; &#x2260; To specify not equals
    &asymp; &#x2248; To specify approximately equals
    < &lt; &#x003c; To specify less than
    &le; &#x2264; To specify less than or equals
    > &gt; &#x003e; To specify greater than
    &ge; &#x2265; To specify greater than or equal
    ± &plusmn; &#x00b1; To specify plus or minus
    &prop; &#x221d; To specify proportional to
    &sum; &#x2211; To specify summation
    &prod; &#x220f; To specify product
    &lfloor; &#x230a; To specify left floor
    &rfloor; &#x230b; To specify right floor
    &lceil; &#x2308; To specify left ceiling
    &rceil; &#x2309; To specify right ceiling
    &hellip; &#x2026; To specify horizontal ellipsis
    &vellip; &#x22ee; To specify vertical ellipsis
    &ctdot; &#x22ef; To specify midline horizontal ellipsis
    &utdot; &#x22f0; To specify diagonal ellipsis
    &dtdot; &#x22f1; To specify downright diagonal ellipsis
    ° &deg; &#x00b0; To specify degrees
    &ang; &#x2220; To specify angle
    &angmsd; &#x2221; To specify measured angle
    &angrt; &#x221f; To specify right angle
    &vangrt; &#x299c; To specify right angle with square
    &lrtri; &#x22bf; To specify right triangle
    &cir; &#x25cb; To specify circle
    &xutri; &#x25b3; To specify triangle
    &squ; &#x25a1; To specify square
    &fltns; &#x25b1; To specify parallelogram
    &spar; &#x2225; To specify parallel
    &npar; &#x2226; To specify not parallel
    &perp; &#x22a5; To specify perpendicular
    &cong; &#x2245; To specify congruent
    &rarr; &#x2192; To specify ray (used with <mover>)
    &harr; &#x2194; To specify line (used with <mover>)
    - (n/a) &#x002d; To specify line segment (used with <mover>)
    &prime; &#x2032; Prime (1st derivative)
    &prime; &#x2033; Double prime (2nd derivative)
    &tprime; &#x2034; Triple prime (3nd derivative)
    &part; &#x2202; To specify partial differential
    δ &delta; &#x0394; To specify increment
    &del; &#x2207; To specify gradient
    &int; &#x222b; To specify integral
    &int; &#x222c; To specify double integral
    &tint; &#x222d; To specify triple integral
    &qint; &#x2a0c; To specify quadruple integral
    &conint; &#x222e; To specify contour integral
    &cwconint; &#x2232; To specify clockwise contour integral
    &awconint; &#x2233; To specify anticlockwise contour integral
    &conint; &#x222f; To specify surface integral
    &cconint; &#x2230; To specify volume integral
    &infin; &#x221e; To specify infinity
    &sdot; &#x22c5; To specify dot product
    &cross; &#x2a2f; To specify cross product
    &vert; &#x2016; To specify norm (magnitude) bars
    &lang; &#x27e8; To specify left angle bracket
    &rang; &#x27e9; To specify right angle bracket
    &compfn; &#x2218; To specify function composition
    &rarr; &#x2192; To specify general function mapping
    &mapsto; &#x21a6; To specify concrete function mapping
    ı &imath; &#x0131; To specify dotless i
    ȷ &jmath; &#x0237; To specify dotless j
    &applyfunction; &af; &#x2061; It is used to specify function application
    &invisibletimes; &it; &#x2062; It is used to specify invisible multiplication
    &invisiblecomma; &ic; &#x2063; It is used to specify invisible separator
    ¬ &not; &#x00ac; To specify negation
    &and; &#x2227; To specify logical conjunction
    &or; &#x2228; To specify logical disjunction
    &veebar; &#x22bb; To specify exclusive disjunction
    &forall; &#x2200; To specify universal quantification
    &exist; &#x2203; To specify existential quantification
    &rarr; &#x21d2; To specify material implication
    &harr; &#x21d4; To specify material equivalence
    &emptysmallsquare; &#x25fb; To specify necessarily
    &loz; &#x25ca; To specify possibly
    &vdash; &#x22a2; To specify provable
    &vdash; &#x22a8; To specify entails
    &there4; &#x2234; To specify therefore
    &empty; &#x2205; To specify the empty set
    &isin; &#x2208; To specify the member of set
    &notin; &#x2209; It specifies not a member of set
    &sube; &#x2286; To specify a subset
    &nsube; &#x2288; To specify not a subset
    &sub; &#x2282; To specify a strict subset
    &nsub; &#x2284; To specify not a strict subset
    &supe; &#x2287; To specify a superset
    &nsupe; &#x2289; To specify not a superset
    &sup; &#x2283; To specify strict superset
    &nsup; &#x2285; To specify not a strict superset
    &cap; &#x2229; To specify intersection
    &cup; &#x222a; To specify union
    &ssetmn; &#x2216; To specify complement
    Capital Letter (C) Small Letter (S) Entities(C) Entities(S) Hex Codes(C) Hex Codes(S)
    Α α &alpha; &alpha; &#x0391; &#x03b1;
    Β β &beta; &beta; &#x0392; &#x03b2;
    Γ γ &gamma; &gamma; &#x0393; &#x03b3;
    Δ δ &delta; &delta; &#x0394; &#x03b4;
    Ε ε &epsilon; &epsilon; &#x0395; &#x03b5;
    Ζ ζ &zeta; &zeta; &#x0396; &#x03b6;
    Η η &eta; &eta; &#x0397; &#x03b7;
    Θ θ &theta; &theta; &#x0398; &#x03b8;
    Ι ι &iota; &iota; &#x0399; &#x03b9;
    Κ κ &kappa; &kappa; &#x039a; &#x03ba;
    Λ λ &lambda; &lambda; &#x039b; &#x03bb;
    Μ μ &mu; &mu; &#x039c; &#x03bc;
    Ν ν &nu; &nu; &#x039d; &#x03bd;
    Ξ ξ &xi; &xi; &#x039e; &#x03be;
    Ο ο &omicron; &omicron; &#x039f; &#x03bf;
    Π π &pi; &pi; &#x03a0; &#x03c0;
    Ρ ρ &rho; &rho; &#x03a1; &#x03c1;
    Σ σ &sigma; &sigma; &#x03a3; &#x03c3;
    Τ τ &tau; &tau; &#x03a4; &#x03c4;
    Υ υ &upsilon; &upsilon; &#x03a5; &#x03c5;
    Φ φ &phi; &phi; &#x03a6; &#x03c6;
    Χ χ &chi; &chi; &#x03a7; &#x03c7;
    Ψ ψ &psi; &psi; &#x03a8; &#x03c8;
    Ω ω &omega; &omega; &#x03a9; &#x03c9;
  5. 我发现我完全低估了这篇论文的难度,它完完全全的超过了我的范畴,我需要从更加基本的论文出发,也许作者二十年前的论文可以作为一个容易入门的吧? Taking on the curse of dimensionality in joint distributions using neural networks

三月十六日 等待变化等待机会

  1. 感觉高等数学根没有学过一样的苍白无力,我想从头补习数学,记忆繁琐的公式也许可以从学习表达式来反复练习:不过我还是取巧从这里拷贝了Taylor Series,这个做法实在是矛盾,不过我把原来的unicode字符改成了无需记忆的可识别的名称,并且去掉了无效的mlabeledtr
    Let f(x) have derivatives of all orders at x=c. n = 0 f ( n ) ( c ) n ! ( x c ) n .
    那么简单的Maclaurin Series也就是当c=0时的特殊形式我打算手写一下:
    n = 0 f ( n ) ( 0 ) n ! x n
    手写公式要写的漂亮要注意挂号不要扩张mo的属性是stretchy="false"
    e n = n = 0 x n n !
    这个是自然指数的泰勒展开,也是最常用的。而这个所谓的几何级数我很惭愧似乎没有印象:
    n = 0 a r n = a 1 r provided  | r | < 1
    它的更加简化的模式
    1 1 + x = n = 0 ( 1 ) n x n 1 1 x = n = 0 x n 1 x = n = 0 ( 1 ) n ( x 1 ) n
  2. 这里是三角函数的泰勒级数:
    cos x = n = 0 ( 1 ) n x 2 n ( 2 n ) ! sin x = n = 0 ( 1 ) n x 2 n + 1 ( 2 n + 1 ) !
  3. 自然对数的泰勒展开也很重要:
    ln x = n = 0 ( 1 ) n 1 ( x 1 ) n n ln ( 1 + x ) = n = 1 ( 1 ) n + 1 x n n

三月十七日 等待变化等待机会

  1. 无意中找到一本不错的电子书,主要是很多数学概念的图解。我之前对于泰勒展开式百思不得其解,而这里非常直观清楚的解释了它的由来,而这层窗户纸一旦捅破就是如此的简单!我现在看来几乎所有的人都能够想到对于多项式如果想要求解那么最直观的就是依次求导数得到它的各个阶的项的系数,这个是多么朴素的想法啊,可是我居然没有想到!当然这里需要的是有级数收敛的概念其实这个还是误解,唯一需要的是函数在该点要无限可导,这个是微积分的核心思想,我始终没有建立起来结果就是对于微积分中可以抓住主要项而忽略次要项不得要领,其实这个是需要求极限来证明是否可以忽略次要项的。

    Derivation of the Formula for the Coefficients of a Power Series.

    One way of finding the coefficients is using Taylor's theorem, derived as follows: Given this polynomial series, f ( z ) = n = 0 c n ( z a ) n (7.1.1) = c 0 + c 1 ( z a ) + c 2 ( z a ) 2 + c 3 ( z a ) 3 + We evaluate both sides of equation above at the point z=a, to obtain: (7.2.1) f ( a ) = c 0 + c 1 ( a a ) + c 2 ( a a ) 2 + c 3 ( a a ) 3 + Since all of the terms, except the first, on the right hand side of are zero, the equation simplifies to: (7.2.2) c 0 = f ( a ) To find the next coefficient, c 1 , we first differentiate (7.2.3) f ( z ) = c 1 + 2 c 2 ( z a ) + 3 c 3 ( z a ) 2 + We then evaluate it at z=a to obtain: (7.2.4) c 1 = f ( a ) We continue to differentiate equation above and then evaluate at z=a, reordering the equation as necessary f ( z ) = 2 c 2 + ( 3 ) ( 2 ) ( z a ) + c 2 = 1 2 f ( a ) The nth coefficient is given by (7.2.5) c n = 1 n ! d n d z n f ( z ) | z = a (7.2.6) = 1 n ! f ( n ) ( a ) By plugging these values of the coefficients into equation , we obtain the following form of the power series: (7.2.7) f ( z ) = n = 0 1 n ! d n d z n f ( a ) ( z a ) n
  2. 这个是一个非常好的关于泰勒展开式求解的视频

三月十八日 等待变化等待机会

  1. 这个真的精髓之言。
    Why should you care about power series? One reason is because they allow us to approximate functions at a point to any desired accuracy.
    这是一个非常的好的直观的工具,它帮助我非常的信服的演示了泰勒展开式来模拟函数的威力和准确度。比如我仅仅使用了最高项11次方就可以很好的拟合正弦曲线了。
    
    x=var('x')
    f(x)=sin(x)
    p1(x)=x
    p2(x)=-x^3/6
    p3(x)=x^5/120
    p4(x)=-x^7/5040
    p5(x)=x^9/362880
    p6(x)=-x^11/39916800
    s(x)=p1(x)+p2(x)+p3(x)+p4(x)+p5(x)
    S=plot(s(x),(x,-5,5),ymin=-2,ymax=2,color=Color('blue'))
    F=plot(f(x),(x,-5,5),ymin=-2,ymax=2,color=Color('red'))
    P1=plot(p1(x),(x,-5,5),ymin=-2,ymax=2,color=Color('green'))
    P2=plot(p2(x),(x,-5,5),ymin=-2,ymax=2,color=Color('green'))
    P3=plot(p3(x),(x,-5,5),ymin=-2,ymax=2,color=Color('green'))
    P4=plot(p4(x),(x,-5,5),ymin=-2,ymax=2,color=Color('green'))
    P5=plot(p5(x),(x,-5,5),ymin=-2,ymax=2,color=Color('green'))
    P6=plot(p6(x),(x,-5,5),ymin=-2,ymax=2,color=Color('green'))
    F+P1+P2+P3+P4+P5+P6+S
    
    针对课后练习题要求解任意的点拟合曲线,我一开始就糊涂了,我还以为这个Maclaurin Series式的公式能够任意的求解,后来看了之前的教程才明白我只能利用泰勒展开式的定义一步一步的求解。 于是这个是求解在函数f=sin(x)当x=π/2的拟合曲线
    
    x=var('x')
    f(x)=sin(x)
    p1(x)=1
    p2(x)=-(x-3.14/2)^2/2
    p3(x)=(x-3.14/2)^4/24
    p4(x)=-(x-3.14/2)^6/720
    p5(x)=(x-3.14/2)^8/40320
    p6(x)=-(x-3.14/2)^10/362880
    s(x)=p1(x)+p2(x)+p3(x)+p4(x)+p5(x)
    S=plot(s(x),(x,-3,7),ymin=-2,ymax=2,color=Color('blue'))
    F=plot(f(x),(x,-3,7),ymin=-2,ymax=2,color=Color('red'))
    P1=plot(p1(x),(x,-3,7),ymin=-2,ymax=2,color=Color('green'))
    P2=plot(p2(x),(x,-3,7),ymin=-2,ymax=2,color=Color('green'))
    P3=plot(p3(x),(x,-3,7),ymin=-2,ymax=2,color=Color('green'))
    P4=plot(p4(x),(x,-3,7),ymin=-2,ymax=2,color=Color('green'))
    P5=plot(p5(x),(x,-3,7),ymin=-2,ymax=2,color=Color('green'))
    P6=plot(p6(x),(x,-3,7),ymin=-2,ymax=2,color=Color('green'))
    F+P1+P2+P3+P4+P5+P6+S
    
    结果是相当的令人满意: 注意红色和蓝色曲线在x=π/2的周围拟合度非常的高。泰勒级数真的是诚不我欺也!我似乎是第一次对于这种微积分的逼近思想有了信服的认识,泰勒多项式虽然是一种近似,但是泰勒级数却是数学上的严格的相等,因为无穷大的逼近就是真的相等而不是有限项的近似。这里的这个工具可以让你选择任意的函数来具象化拟合曲线。非常棒!

三月二十日 等待变化等待机会

  1. 关于泰拉展开的定理的基础是这么一个定理
    Theorem 76 states that the error between a function f(x) and its nth--degree Taylor polynomial pn(x) is Rn(x),where (8.8.7) | R n ( x ) | max | f ( n + 1 ) ( z ) | ( n + 1 ) ! | ( x c ) ( n + 1 ) | If Rn(x) goes to 0 for each x in an interval I as n approaches infinity, we conclude that the function is equal to its Taylor series expansion.
    这里的结论是怎么跳跃的我没有搞明白,因为每一个Rn(x)都趋近于0怎么就能够得到它们的加总也趋近于0呢?就是这个结论是怎么来的呢?
    Let f(x) have derivatives of all orders at x=c,let Rn(x) be as stated in Theorem 76, and let I be an interval on which the Taylor series of f(x) converges. If lim n R n ( x ) = 0 for all x in I,then (8.8.8) f ( x ) = n = 0 f ( n ) ( c ) n ! ( x c ) n    on  I .
    这个就是泰勒定理吧也就是泰勒展开的最最标准的公式吧?

三月二十二日 等待变化等待机会

  1. 这里是Sage的手册,我想学习一些语法使用这个工具来作图有一些直观的感受函数曲线变化。这个是Oregon State大学的在线书非常的好,这些才是美国大学教育的强项。而使用sagemath从安装开始。
  2. sage的颜色很难看,这里说设置成linux好一些:
    
    nick@nick-sager:~$ cat ~/.sage/init.sage 
    %colors Linux
    

三月二十三日 等待变化等待机会

  1. 搜集论文Improving Language Understanding by Generative Pre-Training。现在读起来就有一点感觉了,如果是一个月以前来读的话我可能每一句话都要碰到钉子,经过一个时期的学习,我感觉至少我有一种been there before的感觉,就是说即便不知道准确的含义,但是混了个脸熟的好处就是知道去哪里找,或者说知道它大概的重要性或者方向。
  2. 复习一下逻辑学的三段论
    A premise or premiss is a proposition—a true or false declarative statement—used in an argument to prove the truth of another proposition called the conclusion. Arguments consist of a set of premises and a conclusion.
    这里就是三段论
    Aristotle held that any logical argument could be reduced to two premises and a conclusion.
    很多中文的名词和英文对起来是一个学习的过程。这个既是中文教育的缺点也是一种独特优势。
  3. 这个主意非常的好(Aligning Books and Movies: Towards Story-like Visual Explanations by Watching Movies and Reading Books),它是openAI那篇著名的GPT论文的一个实验素材的来源。
  4. GPT的论文大体上是理解了,但是一触及具体的实验方法就立刻露馅了,因为每一个步骤的细节可能都是前人积累很可能几十上百年的人类成果,单单从最高层来理解都是一个很困难的事情。但是这个也正说明了我的成果,我目前能够在忽略细节的基础上了解一篇论文的主旨,这就足够了。
  5. 有必要这里重新温习一下GPT的概念
    Generative pre-trained transformers (GPT) are a type of large language model (LLM) and a prominent framework for generative artificial intelligence. They are artificial neural networks that are used in natural language processing tasks. GPTs are based on the transformer architecture, pre-trained on large data sets of unlabelled text, and able to generate novel human-like content. As of 2023, most LLMs have these characteristics and are sometimes referred to broadly as GPTs.
    这里有必要在重新引述一下Transformer的概念。它的核心是引入了所谓的attention机制去除了RNN从而减少了训练时间。这些在名词上我知道,但是真正的含义我依然不清楚,比如attention机制是怎么回事我始终搞不懂,这些看样子只有在实现细节才能接触到。那么基于这个概念,GPT论文的核心是什么呢?首先使用Transformer依靠自主学习来使用大量未标记的语言素材来训练大语言模型,然后在不对模型作大调整的前提下来针对其他领域做微调和优化。这个可以称之为本主动学习,因为之前的领域是完全的自主的未分类的学习样本。这个好处是可以充分利用资源,否则人工标记分类是不值得在第一步去做的,人工指导应该放在第二步的特定目标领域去做。这个仿佛是一个培养徒弟的过程,一开始在少林寺里练了七年的挑水做饭的自学是没有师傅指点的,只有等徒弟动心忍性开始领悟的时候师傅才开始点播他。从这一点来看,GPT实际上解决了一个入门的问题,就是我们有大量的训练资料但是不知道要怎么给模型,而如果解决了语言模型那么大量的下一阶段的专项学习就可以事半功倍了。就好比操作系统的成熟与发展都在于一个shell的完善能够让我们在这个平台上自由驰骋。想象看互联网上有着近乎无限的信息可以用来训练,但是如何入手是一个难题,更难的是训练的结果如何转化运用。而GPT开创的正是这个。

三月二十四日 等待变化等待机会

  1. sage是一个很好的概率分布函数的工具,我使用它来加深对于概率曲线的熟悉。
    1. 首先创建四条正态分布
      
      sage: T1 = RealDistribution('gaussian',0.3)
      sage: T2 = RealDistribution('gaussian',1)
      sage: T3 = RealDistribution('gaussian',2)
      sage: T4 = RealDistribution('gaussian',3)
      
    2. 对于四条曲线我分贝设定了不同的颜色
      
      sage: P1=plot(T1, xmin=-5, xmax=5, color="red")
      sage: P2=plot(T2, xmin=-5, xmax=5, color="yellow")
      sage: P3=plot(T3, xmin=-5, xmax=5, color="blue")
      sage: P4=plot(T4, xmin=-5, xmax=5, color="brown")
      
    3. 作图的时候使用Graphics这个函数
      
      sage: g=Graphics()
      sage: g+=P1
      sage: g+=P2
      sage: g+=P3
      sage: g+=P4
      sage: g.show()
      
    4. 假如我想看这些曲线的累积概率曲线
      
      sage: C1=T1.cum_distribution_function
      sage: C2=T2.cum_distribution_function
      sage: C3=T3.cum_distribution_function
      sage: C4=T4.cum_distribution_function
      sage: g=Graphics()
      sage: g+=plot(C1, color="red")
      sage: g+=plot(C2, color="blue")
      sage: g+=plot(C3, color="black")
      sage: g+=plot(C4, color="brown")
      sage: g.show()
      
    5. 我对于我的作图有些怀疑,在比较这个标准的图之后我才意识到,我提供的参数是σ的平方,所以,我要改成σ的平方根来作图:
      
      sage: T1.set_distribution("gaussian", sqrt(0.2))
      sage: T2.set_distribution("gaussian", sqrt(1))
      sage: T3.set_distribution("gaussian", sqrt(5.0))
      sage: T4.set_distribution("gaussian", sqrt(0.5))
      sage: P1=plot(T1, xmin=-5, xmax=5, color="red")
      sage: P2=plot(T2, xmin=-5, xmax=5, color="yellow")
      sage: P3=plot(T3, xmin=-5, xmax=5, color="blue")
      sage: P4=plot(T4, xmin=-5, xmax=5, color="brown")
      sage: g=Graphics()
      sage: g+=P1
      sage: g+=P2
      sage: g+=P3
      sage: g+=P4
      sage: g.show()
      
      现在就和wiki的结果图对上了。
    结论就是gaussian分布的参数是方差的σ而不是它的平方。这个本来是显而易见的我不知道为什么我会糊涂了。

三月二十六日 等待变化等待机会

  1. 有必要学习tensor algebra
    In mathematics, the tensor algebra of a vector space V, denoted T(V) or T•(V), is the algebra of tensors on V (of any rank) with multiplication being the tensor product. It is the free algebra on V, in the sense of being left adjoint to the forgetful functor from algebras to vector spaces: it is the "most general" algebra containing V, in the sense of the corresponding universal property.
    这个定义非常的难懂,我先要明白Tensor Product的定义:
    In mathematics, the tensor product V ⊗ W of two vector spaces V and W (over the same field) is a vector space to which is associated a bilinear map V × W → V ⊗ W that maps a pair ( v , w ) , v ∈ V , w ∈ W to an element of V ⊗ W denoted v ⊗ w .
    那么什么是tensor呢?
    In mathematics, a tensor is an algebraic object that describes a multilinear relationship between sets of algebraic objects related to a vector space. Tensors may map between different objects such as vectors, scalars, and even other tensors. There are many types of tensors, including scalars and vectors (which are the simplest tensors), dual vectors, multilinear maps between vector spaces, and even some operations such as the dot product. Tensors are defined independent of any basis, although they are often referred to by their components in a basis related to a particular coordinate system; those components form an array, which can be thought of as a high-dimensional matrix.

三月二十八日 等待变化等待机会

  1. 我一直觉得tensor product很眼熟,就是想不起来在哪里看到过类似的,直到说这个Cartesian Product才意识到我的潜意识里一直在想这个集合的操作。
    In mathematics, specifically set theory, the Cartesian product of two sets A and B, denoted A × B, is the set of all ordered pairs (a, b) where a is in A and b is in B. In terms of set-builder notation, that is A × B = { ( a , b ) ∣ a ∈ A and b ∈ B } .
    我看的头疼,最后这个简单的说明就解决了我的基本的需求:对于这样两个矩阵 它们的tensor product是什么呢?
  2. 意外的收获是第一次意识到svg原来就是xml的格式。这样子把svg嵌入html其实没有多少的节约。反正都是文字。
  3. 如果你不知道这个所谓的Einstein notation,你可能真的要把脑袋想破也不明白为什么这个等式可以成立! 明明右边看起来像是一个项和∑不相干,其实这个就是爱因斯坦的写法,居然省略了∑

三月二十九日 等待变化等待机会

  1. 工欲善其事,必先利其器。因为很多的数学符号常常的困扰我,不会读也不明白其含义。这里有一个很多数学符号的说明。我觉得相当的不错,因为有很多是不常见的。但是其中的 Hat ˆ 是有另外的意义,通常是单位向量,不知道为什么作者没有列出来,可见这个领域是非常的不规范的。数学家的严谨在于他们的思想,反而在符号上有很大的随意性,从使用各种字母符号就知道是一种约定成俗
  2. 这里是一个非常的典型的对比mathjax和mathml的例子,效果当然是很震撼的。不过我的理解是mathjax是要依赖于脚本来解析吧?而mathml是xml的形式,应该是所谓的自定义不需要额外的资源?
  1. 重新阅读这篇关于使用GPT作自然语言处理的论文。 作者首先列举了一些难题:textual entailment, question answering, semantic similarity assessment, and document classification。这些任何一项都是要穷经皓首才能解决的难题。单单理解问题就是超过普通人想象的困难。
  2. 作者反复提到一个词:discriminatively trained models。这个是什么意思呢?是指的很多训练者在模型转为非训练域作应用的时候必须要再针对使用目标做特化或者优化?还是有一点点通用模型的意味?总而言之,我的理解这篇论文的核心是这个词:generative pre-training,就是GPT的前两个字母,至于最后一个字母TTransformer是之前就已经解决了的现成的模型架构。所以,作者要解决的是如何运用这个模型架构。用作者的话就是训练的时候使用的数据是unlabelled,之后针对具体的运用做微调就是discriminative fine-tuning
    we make use of task-aware input transformations during fine-tuning to achieve effective transfer while requiring minimal changes to the model architecture.
    什么是task-aware input transformations?这个需要再理解。
  3. 第一句话往往是作者最想表达的思想:
    The ability to learn effectively from raw text is crucial to alleviating the dependence on supervised learning in natural language processing (NLP).
    机器学习什么是最重要的?当然是自主学习。什么是最困难的?当然是训练。什么是训练最需要的?当然是训练素材的取得。那么放着广阔无垠的互联网海洋知识库不能使用而只能在海滩边建一个小小的人工水池来模拟学习游泳是不是机器训练的痛点?怎么才能让机器自由的在互联网里畅游而随后能够自然而然的积累经验?这个就是机器学习最紧要的地方。
  4. 作者提到的两个难点我居然以前没有注意到!
    1. First, it is unclear what type of optimization objectives are most effective at learning text representations that are useful for transfer.
    2. Second, there is no consensus on the most effective way to transfer these learned representations to the target task.
    这两个问题是有某种相似性或者联系性的。学以致用是每个人的目标,只有实践才是检验真理的唯一标准。那么在学习中要带着问题和目标去学,这个是被广泛接受的好方式。但是对于机器学习的训练阶段却是不可取的,因为你不能彻底沦为南翔技校学习挖掘机式的培训,换言之,很多时候训练的通用性决定了训练成果的价值。训练时候的某种定向优化彷佛是现行教育里的定向代培,导致了模型固化的偏废。一个方面的优化意味着其他方面的弱化。这个固然是优化的本来意义,但是如果伤筋动骨的大的调整就失去了培训的意义。就是说一事一训的成本太高。第二个问题实际上是第一个问题的进一步深入,就是假如我们要举一反三的能力要怎么做?这个问题实际上比第一个问题还重要。一事一训固然是成本问题,举一反三是能力建设!前者只是成本问题,而后者是无价的。理解了问题的核心就理解了问题的重要性,这个是理解过程的一体两面。
  5. 论文的要义是什么?
    ...we explore a semi-supervised approach for language understanding tasks using a combination of unsupervised pre-training and supervised fine-tuning. Our goal is to learn a universal representation that transfers with little adaptation to a wide range of tasks.
    就是说这个是半自主学习领域的一种尝试,预训练是自主式的学习,而微调是监督学习。而训练的范畴是语言学习,目标则是不限于语言的更广泛的运用,需要很小的适配。这一点我是在第一次读论文所没有意识到的。训练的领域是语言,应用的领域却不一定,这才是巨大的跃进!也就是突破,举一反三才是能力建设。
  6. 为什么是语言?马克思恩格斯认为语言不仅仅是智慧的工具也是智慧的结晶。也许通过学习语言是一条通向智慧的快车道,甚至是唯一的通道。
    We employ a two-stage training procedure. First, we use a language modeling objective on the unlabeled data to learn the initial parameters of a neural network model. Subsequently, we adapt these parameters to a target task using the corresponding supervised objective.
    也许一个能够掌握语言的头脑才是有智能的潜力的头脑,所以,学习必须要先从学习语言开始。语言学习所掌握的参数作调整后可以运用到其他领域。
  7. 作者使用了Transformer的架构来训练,那么回过头来我们随后再去回味为什么是Transformer而不是其他的模型。
    This model choice provides us with a more structured memory for handling long-term dependencies in text, compared to alternatives like recurrent networks, resulting in robust transfer performance across diverse tasks.
    其实回想一下那篇Transformer的论文的标题是什么?是Attention Is All You Need。这个标题在我一开始的时候觉得很突兀,为什么人工智能和Attention杠上了?现在才开始明白,这一切的一切,包括GPT都是在解决一个记忆的问题,这些模型都是人类记忆的某种实现形式。而记忆是有长期短期的,上下文是短期记忆,也就是attention的实质。使用RNN到底不好在哪里呢?我现在并不能知道具体Transformer的multihead attention机制的原理是什么,可是一言以蔽之,肯定是多快好省。这个连YesPrimeMinister里的白痴都能理解的,不用说普通人。一定的,否则为什么要进步。声称是AI的机理究竟是什么?是记忆再现?还是知识存储方式的本质揭示,不管如何,知识本身就是记忆的一种表现形式,去粗取精,拨云见日是知识的提取,也是记忆的优化。能够智能的处理记忆本身就是智能。当然这个是悖论,也是费话。应该说在不失去本质特征前提下的记忆优化是一种智能提取。总之,压缩就是某种智能也是智能的必要,否则就没有智能。
  8. 作者总结说自己的工作主要是自然语言的处理(NLP),而大多数着眼于词语或者短句层级,而作者要瞄准更高的层面:These approaches, however, mainly transfer word-level information, whereas we aim to capture higher-level semantics.。当然更近的是很多工作已经开始在句子层级上的研究了。我觉得这个也是顺理成章的,因为计算量自然就上去了,没有现代的硬件水平支撑,以前想做也困难。作者还提到了更加类似的前人的工作,但作者的改进在于使用Transformer的机制而不是LSTM 被限制了预测的能力在短期。还有其他的就是训练与应用之间需要更大的调整。以后我也找这几篇论文来翻翻。
  9. 作者始终提到训练的目标的问题,这个是回归的目标吗?在自主训练添加额外目标是什么意思?Adding auxiliary unsupervised training objectives is an alternative form of semi-supervised learning. 到底什么是Unsupervised Learning
    Unsupervised learning is a method in machine learning where, in contrast to supervised learning, algorithms learn patterns exclusively from unlabeled data. The hope is that through mimicry, which is an important mode of learning in people, the machine is forced to build a concise representation of its world and then generate imaginative content from it.
    为什么提到这个进化论的概念mimicry?我以为也许是模拟的意思,这个就是英语霸权主义的主要表现形式,我无法完全肯定我的理解。总而言之,训练材料无标记是核心,自主建立某种模式是结果和目标,因此,建立什么目标还是自主学习必要设定的参数。学习是要有目的的。关键是怎么输入这个预设的目标?理解的关键是这个词的含义:language modeling objective。目标要怎么描述?模型的内涵是什么?语言在这里是什么角色?语言即是表达的工具也是内容本身。用语言训练语言模型是语言训练的目标?简单的词语需要大量的理解。很困难。
  10. 我这种笔记学习本身也是一种学习的过程的学习。学习可以有很多种方法,达到的目的也许只有一个,但是检验结果的方法却有几乎无数种,应用固然是目的也是检验的手段。我现在缺乏的正是这种检验与运用的手段。
  11. 什么是语言模型?其实说起来很高大上,现在看起来其实很简单,就是这么个人人都能理解的公式:虽然这个是看似很熟悉的语言模型公式,但是一个细节要指出这里是对于条件概率的对数,这一点要明白是我们为了简化乘法计算而使用对数变为加总,因为贝叶斯条件概率是连乘,这个是常识,但是细节是关键的!
    Given an unsupervised corpus of tokens U = {u1 , . . . , un }, we use a standard language modeling objective to maximize the following likelihood: L 1 ( U ) = i log P ( u i | u i-k ,..., u i-1 ; Θ ) where k is the size of the context window, and the conditional probability P is modeled using a neural network with parameters Θ. These parameters are trained using stochastic gradient descent.
    这里要再复习一下likelihood的定义, 作者针对标准Transformer做了一些修改,这个公式太复杂了,我就偷懒截图如下:
  12. 再次复习一下Softmax函数
    In words, the softmax applies the standard exponential function to each element zi of the input vector z (consisting of K real numbers), and normalizes these values by dividing by the sum of all these exponentials. The normalization ensures that the sum of the components of the output vector σ(z) is 1. The term "softmax" derives from the amplifying effects of the exponential on any maxima in the input vector.

三月三十一日 等待变化等待机会

  1. 预训练之后的微调非常像是在实践检验训练的语言模型,当然这个是我的直觉,因为这个是使用标记的数据来校验吧? 可是这里有些细节还不明白,比如这个所谓的final transformer block's activation hlm究竟是何方神圣?而那个神秘的parameter Wy又是从哪里来的?
    We additionally found that including language modeling as an auxiliary objective to the fine-tuning helped learning by
    1. improving generalization of the supervised model, and
    2. accelerating convergence.
    这里为什么说including language modeling as an auxiliary objective?这里看起来的确像是在训练一个语言模型,为什么说是auxiliary?难道说我们的本意不是在训练语言模型?或者说这些新的标记的数据和原本的训练数据是风马牛不相及?原则上自主学习的确是要求训练数据和检验数据不能重叠,问题是这个fine-tuning算不算是在不同领域的训练,或者是同领域的校验?我始终不明白GPT的机制是怎么样子的,难道使用和训练数据集完全无关的互联网得到的图片和它的alt属性的文字作为一个图形文字对可以作为微调吗?这个如果是对的,在我看来,这个只是利用的GPT语言模型对于语言的模型的有效性来更加准确的理解那些作为标记的alt文字,并不代表GPT模型对于图形的更深入理解。图形归图形,文字归文字,说到底GPT是根据输入的prompt的文字来联系配对的图形和机器学习的图形理解是两码事吧?除非我对于这部分有重大的理解偏差。但是这个部分应该是所谓的GPT的Generative的部分。总之,这些不明白的地方才是GPT的关键部分。
  2. 作者的解释回答了一部分的疑问,就是这个是一个一体两面的模型,不能放弃预训练建立的自主的语言模型,但是也要兼顾微调时候指导的新语言模型,所以,这里的这个联合目标是核心的目标
    Specifically, we optimize the following objective (with weight λ):

    L3(C) = L2(C) + λ ∗ L1(C)

  3. 人类的语言的确是和人类的智能是同步发展的,我个人习惯于自问自答式的学习方式,因为语言不但是知识的载体,也是其组织结构的依托,皮之不存毛之焉附?没有语言的加持很可能人类就不能进化到智慧生物阶段。刘慈欣在《乡村教师》里从高级宇宙智慧体的视角来嘲笑人类这种带宽不超过几十几百个字节每秒的通讯方式,这个在未来的硅基智慧看来是落后原始的,但是这个是传播方式,归根结底知识的组织形式还是要依赖于生物体最容易接触的通讯方式,而串流的字节流似乎是最好的方式。当然《Arrival》里的外星文明使用的是高维度的通讯方式complex written language of the aliens, consisting of palindromic phrases written with circular symbols,也许是接近甚至超过图形化的多角度多层面通讯肯定要在高度进化以后才能想象的到,那时候肯定不会是现在的人类了,也许将来的硅基生命体更加适合。 这里是电影《Arrival》脚本的github repo,真的是不可思议。 这里是解说外星语言文字,和听天书毫无二致。我对于国内书法界的歪风邪气深恶痛绝,简直是糟蹋老祖宗的宝贝,如果它们这群渣滓真的要创新,干脆去写外星书法去吧。
  4. 作者介绍了微调的流程,这幅图我依然似懂非懂。 也许原理上有一个概念,但是作者并没有回答额外的训练参数Wy是怎么来的。作者的解说让我感到有些不可思议,难道人工智能就是这样子实现的吗?虽说熟读唐诗三百首不会作诗也会吟是一种通用的人类学习方法,但是这个真的只能模仿啊。比如pre-trained model was trained on contiguous sequences of text,那么对于微调来说,分类(classification)是不需要专门改动的,而对于文字理解或者说问答(question answering or textual entailment),它的输入是一对句子。我镇的难以想象AI就是这么练成的,一个对于阅读了大量素材之后就能侃侃而谈式的为人类指点迷津?
    • Textual entailment: For entailment tasks, we concatenate the premise p and hypothesis h token sequences, with a delimiter token ($) in between.
    • Similarity For similarity tasks, there is no inherent ordering of the two sentences being compared. To reflect this, we modify the input sequence to contain both possible sentence orderings (with a delimiter in between) and process each independently to produce two sequence representations hlm which are added element-wise before being fed into the linear output layer.
    • Question Answering and Commonsense Reasoning For these tasks, we are given a context document z, a question q, and a set of possible answers {ak }. We concatenate the document context and question with each possible answer, adding a delimiter token in between to get [z; q; $; ak ]. Each of these sequences are processed independently with our model and then normalized via a softmax layer to produce an output distribution over possible answers.
    这个看到了吧!AI是怎么训练的?就是背答案,对于多重选择是最典型的,就是把每一个答案选择连同原文和问题一个个的单独输入看看条件概率是不是最大。这个你不能说不对,但是总觉得似乎难以置信。
  5. 这个是论文训练的数据bookcorpus,似乎最近OpenAI的头在记者访问中被问到授权数据的问题跟这个有关系吧?这个是下载bookcorpus的链接。顺便复习一下perplexity的概念,它越大越难猜对。
  6. 然后这里又遇到最最核心的细节,就是模型的细节:12-layer decoder-only transformer with masked self-attention heads (768 dimensional states and 12 attention heads)。这里每一个字都很重要。我首先还是要去理解decoder的层数是什么意思,从概念上当然好像是神经网络,但是我觉得肯定不是,因为神经网络的层数是非常大的。而反反复复出现的maskedunmasked让我摸不着头脑,至于说self-attention就更是Transformer的精髓所在。所以一遇到真正的干货就卡壳了。看样子我需要回过头来读Transformer论文。今天就到这里吧?

四月一日 等待变化等待机会

  1. 第一个概念是BLEU(bilingual evaluation understudy)
    BLEU (bilingual evaluation understudy) is an algorithm for evaluating the quality of text which has been machine-translated from one natural language to another. Quality is considered to be the correspondence between a machine's output and that of a human: "the closer a machine translation is to a professional human translation, the better it is" – this is the central idea behind BLEU. Invented at IBM in 2001, BLEU was one of the first metrics to claim a high correlation with human judgements of quality, and remains one of the most popular automated and inexpensive metrics.
    这个东西实在是平淡无奇,为什么IBM会和平淡无奇经常的挂钩呢?一个纯粹要靠和主观人为的结果来比较的算法能够自动化吗?也许部分吧?这个本质上和图灵实验一样的是一种非常的别扭的定义方式。这个和之前看到的universal property相比就落后了一大街,一个事物固然可以以它的构成方法来定义,但是更为高明或者有普遍意义的是以它的固有的属性来定义。目前AI这个领域之所以充斥了太多这种只能简单的凭借其生成方式来定义的现象归根结底还是因为我们对于它的本质属性把握的缺失,一个工业标准制定的如同手工艺制品的鉴定水平,无法批量化客观化。好像鉴宝大会的专家系统一样。
  2. 复习一下AttentionDefinition。要学习掌握Attention先要理解为什么,也就是它的前任之一:RNN。简而言之,RNN是一种模仿人类的记忆的模式,它的输入是带有时间信息的,而这个其实是合理的,并且类似递归效应,结果会对下一次的结果有影响,这个也有人类记忆的影子。这个并非不好,但是这篇GPT-paper要解决的并非要否定这一点,主要是针对输入和输出元素位置的敏感信息部分,作为这个RNN记忆模型天然的就是含有时间信息,那么位置敏感是自然的,这样子对于联系输入输出里元素它们之间的距离成为天然屏障。这个是它的缺点。现代人对于信息洪流普遍能够处理的注意力带宽就是三秒,短期记忆限制了人类的联系能力,政客们针对于此有很多的把戏。
  3. 什么是attention呢?这个本来是认知领域的概念:
    Attention is the concentration of awareness on some phenomenon to the exclusion of other stimuli. It is a process of selectively concentrating on a discrete aspect of information, whether considered subjective or objective.
    在机器学习里它的定义是这样子的:
    Machine learning-based attention is a mechanism which intuitively mimics cognitive attention. It calculates "soft" weights for each word, more precisely for its embedding, in the context window. These weights can be computed either in parallel (such as in transformers) or sequentially (such as recurrent neural networks). "Soft" weights can change during each runtime, in contrast to "hard" weights, which are (pre-)trained and fine-tuned and remain frozen afterwards.
    所以,这个是一个影响word embedding的各个值的过程。也就是换言之,word embedding里包含了全部的信息,上下文窗口范围内的重点划线词字是靠它的向量的转动来体现的。
  4. RNN有固有的难题,Attention某种程度上解决了Attention allows the calculation of the hidden representation of a token equal access to any part of a sentence directly, rather than only through the previous hidden state. RNN的问题是什么?the weaknesses of leveraging information from the hidden outputs。为什么?favor more recent information contained in words at the end of a sentence,,这个本来就是RNN的地层逻辑,时间敏感性,哪怕是同一个句子,也是后面的词优先前面的词,这个是误解的,本来是它的优势,因为人类的记忆就是如此,甚至很多电子电路也是如此,取决于你要多大的缓冲区,好像网络设备一样有这个窗口期开多大的难题一样,资源是有限的,时间延迟也是一种资源有限的体现。总之,attention从某种程度解决一定也是付出代价,它自己说:at the cost of reduced effective resolution due to averaging attention-weighted positions,这里的averaging attention-weighted positions是什么意思我还不懂,但是结果是明白的:reduced to a constant number of operations 估计是一个常量级别的查询动作?但是它也有后续补偿机制:counteract with Multi-Head Attention,所以,这个是以后阅读的重点理解部分。
  5. 这里要特别强调self-attention
    Self-attention, sometimes called intra-attention is an attention mechanism relating different positions of a single sequence in order to compute a representation of the sequence.
    可以理解为在当前句子里或者是窗口期内?总之目的是对冲位置敏感性。位置不是不敏感,而是在当前句子里不应该成为障碍。尤其是长句子。其实我需要补课word embedding的细节才能真正理解这其中的关键。
  6. 这里有一个实践word embedding的工具。还是要实践!这里谈到的依靠直觉来设计word embedding的向量非常的有启发性,值得深入思考理解!等吃完早饭再来看过。

四月二日 等待变化等待机会

  1. 实践也许是最好的老师,因为很多人善于从观察反馈中学习。我感觉纸上得来终觉浅是有道理的就在于很多理论的宣讲是有类似于attention机制的取舍的,因为要强调一些重点就有意无意忽视一些细节。成败虽然在于细节,但是失败也往往是挂一漏万的过于关注局部,只见树木不见森林。
  2. 对于设计一个字词的表达的数据结构就能够考验出一个人对于知识技能的把我。如果我们设计的目的在于存储与查找这种单一的目的,那么自然关注的是搜索效率,可是在word embedding的范畴里,我们希望达到另一个目的,就是字和字之间的相似度,甚至我们希望一词多义,那么传统的index是无法满足的,因为index说到底还是一维的线性关系,一个字在不同的上下文有不同的意思这个要怎么表达呢?传统的数据结构是苍白无力的。一定是多维度的,但是一言以蔽之,多维度为什么又要是浮点数,为什么整数的向量表达不能满足呢?这个team有一个架构keras也许能够帮助理解具体的细节。tensorflow的embedding也讲了一些细节,不过是假定你不是小白的细节。我决定跟随这个tensorflow的tutorial一个核心的要点是我们不仅仅是要表达如何定位一个词在词库中的地位,更加重要的是要表达这个词和它有紧密联系的词的关系程度。一词多义是一个特殊意义的关系,更加普遍的是有上下文经常出现在一起的词之间的紧密关系,这个关系的表达才是数据结构的设计核心。而查找单个词在整个词库的位置则是一个相对不重要的方面。
  3. 仔细体会这个教程,究竟为什么和怎么设计word embedding。先感受一下视觉的震撼!看看这个embedding projector

四月三日 等待变化等待机会

  1. 这个word embedding教程值得深入反复学习。
  2. 一直有一个numa的错误,我的笔记本怎么会有numa呢?但是似乎tensorboard运行的时候认为这个是一个错误。看看这个能不能修复这个问题。
    
    sudo echo 0 | sudo tee -a /sys/bus/pci/devices/0000\:01\:00.0/numa_node
    
    但是似乎这个并不是源头错误,而是tensorRT没有安装的关系。这个是为了安装运行tensorboard,它并不是必须的,但是我想看看效果。
  3. 这里的missing feature instruction的解说让我十分的费解,究竟这个是对于CPU做优化吗?这里是github的源代码,看起来是很简单,但是用意是什么我有些糊涂了。我于是检查我自己的笔记本电脑的cpu信息:
    
    nick@nick-sager:/tmp$ sudo lshw -C cpu
      *-cpu                     
           description: CPU
           product: 13th Gen Intel(R) Core(TM) i9-13900HX
           vendor: Intel Corp.
           physical id: 4
           bus info: cpu@0
           version: 6.183.1
           serial: To Be Filled By O.E.M.
           slot: U29
           size: 1905MHz
           capacity: 5200MHz
           width: 64 bits
           clock: 100MHz
           capabilities: lm fpu fpu_exception wp vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp x86-64 constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb ssbd ibrs ibpb stibp ibrs_enhanced tpr_shadow flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid rdseed adx smap clflushopt clwb intel_pt sha_ni xsaveopt xsavec xgetbv1 xsaves split_lock_detect avx_vnni dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp hwp_pkg_req hfi vnmi umip pku ospke waitpkg gfni vaes vpclmulqdq rdpid movdiri movdir64b fsrm md_clear serialize arch_lbr ibt flush_l1d arch_capabilities cpufreq
           configuration: cores=24 enabledcores=24 microcode=285 threads=32
    
    所以,现在我才理解了,就是在编译tensor库的时候,如果编译者的系统没有支持avx/avx2的cpu feature,或者编译者有意识的屏蔽掉这两个feature,故意去除这两个预定义的宏__AVX__,__AVX2__,我记得这个应该是安装gcc之类的预定义吧?似乎是在编译gcc的时候你需要设置的,或者gcc编译的时候自动识别?如果我是从源码编译的时候吧?,总而言之,编译者没有设置那么库就会自动收集这两个运行期的系统cpu feature,然后报警让你重新编译来优化。
  4. 但是我安装了tensorrt似乎还是报错说找不到,看看这里的如何安装GPU 首先我要明确我的GPU型号:
    
    ick@nick-sager:/tmp$ lspci | grep -i nvidia
    0000:01:00.0 VGA compatible controller: NVIDIA Corporation AD107M [GeForce RTX 4050 Max-Q / Mobile] (rev a1)
    0000:01:00.1 Audio device: NVIDIA Corporation Device 22be (rev a1)
    
    tensorflow官方指引nvidia官方安装网站。我对于这个有些发憷,因为似乎这个和ubuntu的官方有冲突?不过我已经安装了550.40.07,这个是nvidia-smi的结果,所以,我只需要安装tensorflow的GPU版本就可以了。
    
    pip install tensorflow[and-cuda]
    
    而我以前是安装的默认的cpu版本:
    
    pip install tensorflow
    
    这个应该才是问题。
  5. 前两天一个小问题是find的regex选项,它的*是前面一个字符的若干重复而不能空泛的单独定义,所以,任意字符需要定义为.*,这一点是一个教训。
  6. 这里是两个试金石
    
    Verify the CPU setup:
    
    python3 -c "import tensorflow as tf; print(tf.reduce_sum(tf.random.normal([1000, 1000])))"
    
    If a tensor is returned, you've installed TensorFlow successfully.
    
    Verify the GPU setup:
    
    python3 -c "import tensorflow as tf; print(tf.config.list_physical_devices('GPU'))"
    
    If a list of GPU devices is returned, you've installed TensorFlow successfully.
    
    我的GPU返回是空,我决定冒险升级我的驱动。这个是非常的冒险,因为很有可能又把内核版本搞乱,因为nvidia的驱动需要动态内核编译,非常的烦人,难怪当年Linus对于黄仁勋竖中指。不过我现在是通过ubuntu官方的更新包,它自动的在编译内核驱动,也许好一些吧?ubuntu要我订阅什么pro,虽然是免费的还是让我惴惴不安。现在重启看看。
  7. 问题还是一样,所以我怀疑我没有安装基本的库。似乎cuDNN SDK我没有安装?

四月四日 等待变化等待机会

  1. 我的系统应该是出现了混乱,只好把tensorflow先卸载再安装。我觉得我的问题是python找不到这个tensorRT,但是我的ubuntu系统的包是已经安装过了,那么应该是python的接口没有安装吧?总之,我看到nvidia把这个软件生态搞得越来越封闭是不太高兴的,这个要安装tensorRT究竟是怎么个东西我是懒得理解了。pip不提供搜索功能,所以,只能到网上搜索。我对于搜索的结果感到十分的困惑,现在的python和当年的java虚拟环境一样的混乱。
  2. 如果机器学习是绕不开tensorflow的话,那么熟悉甚至编译应该是一个必修课。
    1. 这里是tensorflow编译指南
    2. 一些必要安装环境:
      
      sudo apt install python3-dev python3-pip
      
    3. 然后是安装Bazel,指南说是使用Bazelisk来安装Bazel。这个我还在实验中。我想起来之前编译c++标准文档的node.js里用到过,但是不理解。
    4. 谷歌这些人搞得GO就是复杂,当然我是赞成的,没有版本管理的任何工具都是一个噩梦。就是说Bazelisk管理着Bazel的版本。所以,这个回答了我的一个疑问,就是Bazelisk的版本似乎没有人在意了,因为它就是一个管家而已我们关心的是干活的Bazel版本对了就行了。
    5. 就是说Bazel的版本号的控制是依赖这个机制。
    6. 我对于安装Bazel的机制依然感到困惑,甚至于它的功能依然感到不可理解,究竟它是一个make的替代吗?为什么这么多平台居然没有ubuntu的单独支持,难道是debian的普通版本就可以了?
    7. 果然还是要读wiki的定义,
      Bazel (/ˈbeɪzəl/[3]) is a free and open-source software tool used for the automation of building and testing software.[2] Google uses the build tool Blaze internally[4] and released an open-sourced port of the Blaze tool as Bazel, named as an anagram of Blaze.[5] Bazel was first released in March 2015 and was in beta status by September 2015.[6] Version 1.0 was released in October 2019.

      Similar to build tools like Make, Apache Ant, and Apache Maven,[2][5] Bazel builds software applications from source code using rules. Rules and macros are created in the Starlark language (previously called Skylark),[8] a dialect of Python.[5] There are built-in rules for building software written in Java, Kotlin, Scala, C, C++, Go, Python, Rust, JavaScript, Objective-C, and bash scripts.[5][6] Bazel can produce software application packages suitable for deployment for the Android and iOS operating systems.

      这个是一个核心的特点:
      it creates a new directory and fills it with symlinks to the explicit input dependencies for the rule
      ,就是把include的头文件全部清晰的表达为软链接,这个的确是一个好方法。
    8. Bazel对于编译的各个软件使用严格的版本控制,不依赖于时间戳,而是用文件的数字签名,而对于bazel本身的版本又加了一个Bazelisk来控制,谷歌这些人确实是狠。
  3. 我的openVPN一直叫着要我输入这个,我决定把这个auth-user-pass注释掉,因为我不想让它自动运行,也没有设定为startup的服务。
  4. 编译tensorflow的确给了很严格的控制它的能力,这个是我第一次接触GPU的Compute Capability
    The compute capability of a device is represented by a version number, also sometimes called its “SM version”. This version number identifies the features supported by the GPU hardware and is used by applications at runtime to determine which hardware features and/or instructions are available on the present GPU.

    The compute capability comprises a major revision number X and a minor revision number Y and is denoted by X.Y.

    我一开始还以为是类似于CPU feature一样的一些名词,原来是用版本数字代替,这个好。我的显卡的能力是: GeForce RTX 4050 8.9
    GeForce RTX 4050 Laptop GPU
    NVIDIA CUDA Cores

    2560

    Boost Clock

    1605 - 2370 MHz

    Memory Size

    6 GB

    Memory Type

    GDDR6

  5. tensorflow的默认编译器是clang,这个看样子是逼我安装了,我之前还犹豫要不要用GCC,看来还是不要折腾了。
    
    sudo apt-get update && sudo apt-get install -y llvm-17 clang-17
    
    但是很显然的我的ubuntu官方不可能有这么高的版本,为什么要这么新的版本啊?The current supported version is LLVM/Clang 17. 看样子只能照着做了:
    
    wget https://github.com/llvm/llvm-project/releases/download/llvmorg-17.0.2/clang+llvm-17.0.2-x86_64-linux-gnu-ubuntu-22.04.tar.xz
    tar -xvf clang+llvm-17.0.2-x86_64-linux-gnu-ubuntu-22.04.tar.xz
    
    不过平心而论clang确实比GCC要略胜一筹,我对于clang的稳定性还是比较信任的。但是居然clang是这样子安装的?我对于这个原始的做法总是惴惴不安。
    
    cp -r clang+llvm-17.0.2-x86_64-linux-gnu-ubuntu-22.04/* /usr
    
    不过结果似乎也是不用操心,反正clang的版本都是覆盖。
    nick@nick-sager:~/Downloads$ clang --version clang version 17.0.2 (https://github.com/llvm/llvm-project b2417f51dbbd7435eb3aaf203de24de6754da50e) Target: x86_64-unknown-linux-gnu Thread model: posix InstalledDir: /usr/bin
  6. 核心的难点还是在GPU相关的驱动软件的支持上

    The following NVIDIA® software are only required for GPU support.

    这几个都是nvidia的东西,很讨厌的。从nvidia-smi我可以知道我的GPUdriver版本是够了:NVIDIA-SMI 550.54.15 Driver Version: 550.54.15 CUDA Version: 12.4
    1. toolkit我是使用ubuntu官方的cuda-toolkit-12-3
    2. 这里需要理解cuda有11和12两个平台,看样子这个也是一个复杂的领域,我使用ubuntu的官方的安装包cudnn9-cuda-12-3应该和nvidia的差不多吧?不过我吃不透ubuntu自己的安装脚本:nvidia-cudnn,似乎的版本是cuda11的,那么我还是安装nvidia的吧:
      
      wget https://developer.download.nvidia.com/compute/cudnn/9.0.0/local_installers/cudnn-local-repo-ubuntu2204-9.0.0_1.0-1_amd64.deb
      sudo dpkg -i cudnn-local-repo-ubuntu2204-9.0.0_1.0-1_amd64.deb
      sudo cp /var/cudnn-local-repo-ubuntu2204-9.0.0/cudnn-*-keyring.gpg /usr/share/keyrings/
      sudo apt-get update
      sudo apt-get -y install cudnn
      
      不过看到这里我似乎觉得我直接安装cudnn就可以了。没必要安装localrepo吧?这里先明确一下概念:
      The NVIDIA CUDA Deep Neural Network library (cuDNN) is a GPU-accelerated library of primitives for deep neural networks. cuDNN provides highly tuned implementations for standard routines such as forward and backward convolution, attention, matmul, pooling, and normalization.
      所以,关键字是GPU-accelerated library就是GPU加速,但是这个几乎就是费话,否则我干嘛要装你呢?只不过是针对deep neural networks。这里提到的几个标准很重要!
    3. 其实我一直有问题的是tensorRT这个可选的库,一直不理解,看看这个文档吧:
      NVIDIA® TensorRT™ is an SDK for optimizing trained deep learning models to enable high-performance inference. TensorRT contains a deep learning inference optimizer for trained deep learning models, and a runtime for execution. After you have trained your deep learning model in a framework of your choice, TensorRT enables you to run it with higher throughput and lower latency.
      所以,这里是关于deep learning inference,这个具体是什么呢?
    4. 关于tensorRT的安装,这里的指南我还是不确定,因为ubuntu的官方安装包tensorrt据说是c++/python的接口都齐全了,为什么我还是需要再次使用pip来安装呢?我只能理解是不同的路径的殊涂同归?不过编译所谓的
      
      python3 -m pip install --pre --upgrade tensorrt
      
      这里说是
      The above pip command will pull in all the required CUDA libraries in Python wheel format from PyPI because they are dependencies of the TensorRT Python wheel. Also, it will upgrade tensorrt to the latest version if you had a previous version installed.
      在我看来这个所谓的dependency是编译期的并非运行期吧?

四月六日 等待变化等待机会

  1. 在编译tensorflow的configure里你看到有一系列的选项,这个在.bazelrc里有详细的选项,不过我还是按照最基本的configure的流程。这里遇到bazel的安装的问题,因为版本6.5是必须的。这里是专门针对ubuntu的指引。
    
    sudo apt install apt-transport-https curl gnupg -y
    curl -fsSL https://bazel.build/bazel-release.pub.gpg | gpg --dearmor >bazel-archive-keyring.gpg
    sudo mv bazel-archive-keyring.gpg /usr/share/keyrings
    echo "deb [arch=amd64 signed-by=/usr/share/keyrings/bazel-archive-keyring.gpg] https://storage.googleapis.com/bazel-apt stable jdk1.8" | sudo tee /etc/apt/sources.list.d/bazel.list
    
    这个是一个比较典型的通用流程,添加gpg key看来是一个趋势了,应该是可以过滤掉大多数的无谓地下载请求吧。使用官方的安装包我比较放心。这里有一个插曲,就是ubuntu有一个所谓的bazel-bootstrap的包,我之前不明所以,就安装了,我的猜测是类似于官方的下载安装脚本之类的。这个和使用现在的apt安装有冲突必须删除。 这个jdk的安装环境似乎是必须的,否则bazel去下载什么jvm又会失败:
    
    sudo apt install default-jdk
    
  2. 我感觉问题其实很多,也许应该尝试一下docker编译的方式。
    1. 安装docker
      
      sudo apt install gnome-terminal
      # Add Docker's official GPG key:
      sudo apt-get update
      sudo apt-get install ca-certificates curl
      sudo install -m 0755 -d /etc/apt/keyrings
      sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
      sudo chmod a+r /etc/apt/keyrings/docker.asc
      
      # Add the repository to Apt sources:
      echo \
        "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
        $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
        sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
      sudo apt-get update
      
      然后是安装最新版本
      
      sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
      
      测试docker:
      
      sudo docker run hello-world
      
    2. 接下来是安装nvidia的container的支持,这个又是一个long story!
      
      curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \
        && curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
          sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
          sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
      
      然后是安装包
      
      sudo apt-get update
      sudo apt-get install -y nvidia-container-toolkit
      
    3. 然后我们需要下载tensorflow的docker image。这里我才意识到我的docker是必须root accessed,这样子感觉有什么设置的问题?
      
      docker pull tensorflow/tensorflow                     # latest stable release
      docker pull tensorflow/tensorflow:devel-gpu           # nightly dev release w/ GPU support
      docker pull tensorflow/tensorflow:latest-gpu-jupyter  # latest release w/ GPU support and Jupyter
      
      就是说安装和运行docker都要sudo,那么这个是否有危险呢?
    4. 运行docker在bash里的话这个命令可以map到我自己的用户比较好
      
      sudo docker run -u $(id -u):$(id -g) -it tensorflow/tensorflow bash
      
    5. 这个时候我才意识到我使用的是cpu-only的docker,需要这个gpu docker
      
      docker pull tensorflow/tensorflow:devel-gpu
      docker run --gpus all -it -w /tensorflow -v $PWD:/mnt -e HOST_PERMS="$(id -u):$(id -g)" \
          tensorflow/tensorflow:devel-gpu bash
      git pull  # within the container, download the latest source code
      
      这个总是报错,我只能去除掉--gpus all这个选项,并且,这个docker是默认root环境的,我无法用映射成我自己的用户名的方式。应该是安全的吧?我的理解是使用root的方式mount的话会有一些垃圾清理的问题,并不一定算是系统的威胁吧?
      
      ________                               _______________                
      ___  __/__________________________________  ____/__  /________      __
      __  /  _  _ \_  __ \_  ___/  __ \_  ___/_  /_   __  /_  __ \_ | /| / /
      _  /   /  __/  / / /(__  )/ /_/ /  /   _  __/   _  / / /_/ /_ |/ |/ / 
      /_/    \___//_/ /_//____/ \____//_/    /_/      /_/  \____/____/|__/
      
      
      WARNING: You are running this container as root, which can cause new files in
      mounted volumes to be created as the root user on your host machine.
      
      To avoid this, run the container by specifying your user's userid:
      
      $ docker run -u $(id -u):$(id -g) args...
      
      我是喜欢这个tensorflow的logo。
    6. 在docker里更新git repo遇到这个错误
      
      error: RPC failed; curl 92 HTTP/2 stream 0 was not closed cleanly: CANCEL (err 8)
      fatal: the remote end hung up unexpectedly
      fatal: early EOF
      fatal: index-pack failed
      
      这里
      
      git config --global http.version HTTP/1.1
      
      还有说是增加buffer
      
      git config --global http.postBuffer 157286400
      
    7. 另一种想法就是这个image是不让你再更新的了?也许直接编译
      
      bazel build //tensorflow/tools/pip_package:wheel --repo_env=WHEEL_NAME=tensorflow --config=cuda --config=opt
      chown $HOST_PERMS bazel-bin/tensorflow/tools/pip_package/wheel_house/tensorflow-version-tags.whl
      
    8. 所以,在docker环境下还是要先安装jdk
    总而言之,使用docker是一个很复杂的过程,不使用docker是一个更加无尽头的复杂的过程!这个是一个大趋势!我一向对于虚拟机有抵触,因为尤其是使用GPU这类硬件加速的需求下使用虚拟机无异于缘木求鱼,但是docker应该是一个例外,这个从内核隔绝来实现的虚拟技术应该是损耗最小的虚拟技术,甚至于我觉得从原理来看是最好的解决办法。所以,无论是snap还是docker应该是我进一步需要增强的方向。
  3. 我似乎终于开始明白一些浅显的道理,就是配置tensorflow的环境其实很麻烦,一方面最最基本的硬件驱动是逃不掉的,这个只要你需要使用nvidia的gpu是无论如何必须的前提,但是另一方面nvidia的一整套的软件库如cuda/dnn/tensorrt之类是很麻烦的,那么如果你使用tensorflow的docker的image的话,这些软件库的配置就省心了,那么在这样的环境下编译tensorflow就简单很多了,这个是我的理解,这个是说的很明白的道理,但是我之前是无论如何无法理解的。当然这个还是我的猜想,要实际去验证才明确。
  4. 这个关于docker的安全指导值得我随后学习。
  5. 这个是docker入门教育,以前公司花钱让你学都学不进去,现在有些后悔了。
    Docker is a set of platform as a service (PaaS) products that use OS-level virtualization to deliver software in packages called containers.[4] The service has both free and premium tiers. The software that hosts the containers is called Docker Engine.[5] It was first released in 2013 and is developed by Docker, Inc.
    我原来认为docker就是cgroup,看来是错误的认识看来也不错
    Because all of the containers share the services of a single operating system kernel, they use fewer resources than virtual machines
    When running on Linux, Docker uses the resource isolation features of the Linux kernel (such as cgroups and kernel namespaces) and a union-capable file system (such as OverlayFS)[10] to allow containers to run within a single Linux instance, avoiding the overhead of starting and maintaining virtual machines.
  6. 对于我的docker的问题,这里重启docker似乎可以解决,
    
    sudo apt install -y nvidia-docker2
    sudo systemctl daemon-reload
    sudo systemctl restart docker
    
    因为我之前总是遇到docker: error response from daemon: could not select device driver "" with capabilities: [[gpu]].的错误。
  7. 我编译的时候遇到更多的错误,使用clang总是遇到各种各样的头文件的问题,比如cstddef.h之类的,我于是转而使用gcc,但是遇到 /usr/include/x86_64-linux-gnu/NvUtils.h找不到的问题,我找了一下才意识到这个是我安装的标准的tensorrt-dev库的问题:
    dpkg -L libnvinfer-dev 
    这个是看不到头文件的,我不知道这个是否是早期的包?那么看看官方的做法吧。 不过还是要先理解一下什么是tensorRT?
    The core of NVIDIA® TensorRT™ is a C++ library that facilitates high-performance inference on NVIDIA graphics processing units (GPUs). TensorRT takes a trained network, which consists of a network definition and a set of trained parameters, and produces a highly optimized runtime engine that performs inference for that network.
    难道是把模型也包含在里面了吗?
  8. 今天有些累了,焦头烂额。

四月七日 等待变化等待机会

  1. 我还是不太理解tensorRT到底是个什么东西。
    TensorRT provides APIs via C++ and Python that help to express deep learning models via the Network Definition API or load a pre-defined model via the ONNX parser that allow TensorRT to optimize and run them on an NVIDIA GPU. TensorRT applies graph optimizations, layer fusions, among other optimizations, while also finding the fastest implementation of that model leveraging a diverse collection of highly optimized kernels. TensorRT also supplies a runtime that you can use to execute this network on all of NVIDIA’s GPU’s from the NVIDIA Volta™ generation onwards.
    难道就是你可以操纵模型?似乎是说你给我模型参数我给你生成模型或者直接调现成的模型?这个Open Neural Network Exchange (ONNX) parser是一个关键的概念:
    The Open Neural Network Exchange (ONNX) is an open-source artificial intelligence ecosystem of technology companies and research organizations that establish open standards for representing machine learning algorithms and software tools to promote innovation and collaboration in the AI sector. ONNX is available on GitHub. ONNX was originally named Toffee and was developed by the PyTorch team at Facebook.
    它具体是什么呢?
    ONNX provides definitions of an extensible computation graph model, built-in operators and standard data types, focused on inferencing (evaluation). Each computation dataflow graph is a list of nodes that form an acyclic graph. Nodes have inputs and outputs. Each node is a call to an operator. Metadata documents the graph. Built-in operators are to be available on each ONNX-supporting framework.
    基本是三样:操作流程,操作运算的定义,操作数据的定义。这个是万变不离其宗的。
  2. 这里有一个AI的相关软件的比较,了解一下。
  3. 我对于ubuntu官方的安装包感到有些困惑,是否那些动态库都安装了呢?我现在才理解了一点,原来nvidia让你下载一个所谓的本地安装包,而这个本地安装包是众多的安装包的集合:
    
    nick@nick-sager:~/Downloads/NVidia$ dpkg -L nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8
    /.
    /etc
    /etc/apt
    /etc/apt/sources.list.d
    /etc/apt/sources.list.d/nv-tensorrt-local-ubuntu2204-10.0.0-cuda-11.8.list
    /usr
    /usr/share
    /usr/share/doc
    /usr/share/doc/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8
    /usr/share/doc/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/changelog.Debian.gz
    /var
    /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8
    /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/2B368663.pub
    /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/InRelease
    /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/Local.md5
    /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/Local.md5.gpg
    /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/Packages
    /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/Packages.gz
    /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/Release
    /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/Release.gpg
    /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/libnvinfer-bin_10.0.0.6-1+cuda11.8_amd64.deb
    /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/libnvinfer-dev_10.0.0.6-1+cuda11.8_amd64.deb
    /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/libnvinfer-dispatch-dev_10.0.0.6-1+cuda11.8_amd64.deb
    /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/libnvinfer-dispatch10_10.0.0.6-1+cuda11.8_amd64.deb
    /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/libnvinfer-headers-dev_10.0.0.6-1+cuda11.8_amd64.deb
    /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/libnvinfer-headers-plugin-dev_10.0.0.6-1+cuda11.8_amd64.deb
    /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/libnvinfer-lean-dev_10.0.0.6-1+cuda11.8_amd64.deb
    /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/libnvinfer-lean10_10.0.0.6-1+cuda11.8_amd64.deb
    /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/libnvinfer-plugin-dev_10.0.0.6-1+cuda11.8_amd64.deb
    /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/libnvinfer-plugin10_10.0.0.6-1+cuda11.8_amd64.deb
    /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/libnvinfer-samples_10.0.0.6-1+cuda11.8_all.deb
    /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/libnvinfer-vc-plugin-dev_10.0.0.6-1+cuda11.8_amd64.deb
    /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/libnvinfer-vc-plugin10_10.0.0.6-1+cuda11.8_amd64.deb
    /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/libnvinfer10_10.0.0.6-1+cuda11.8_amd64.deb
    /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/libnvonnxparsers-dev_10.0.0.6-1+cuda11.8_amd64.deb
    /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/libnvonnxparsers10_10.0.0.6-1+cuda11.8_amd64.deb
    /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/nv-tensorrt-local-2B368663-keyring.gpg
    /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/onnx-graphsurgeon_10.0.0.6-1+cuda11.8_amd64.deb
    /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/python3-libnvinfer-dev_10.0.0.6-1+cuda11.8_amd64.deb
    /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/python3-libnvinfer-dispatch_10.0.0.6-1+cuda11.8_amd64.deb
    /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/python3-libnvinfer-lean_10.0.0.6-1+cuda11.8_amd64.deb
    /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/python3-libnvinfer_10.0.0.6-1+cuda11.8_amd64.deb
    /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/tensorrt-dev_10.0.0.6-1+cuda11.8_amd64.deb
    /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/tensorrt-libs_10.0.0.6-1+cuda11.8_amd64.deb
    /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/tensorrt_10.0.0.6-1+cuda11.8_amd64.deb
    
    而这里最关键的是它增添了一个source_list文件
    
    nick@nick-sager:~/Downloads/NVidia$ cat /etc/apt/sources.list.d/nv-tensorrt-local-ubuntu2204-10.0.0-cuda-11.8.list
    deb [signed-by=/usr/share/keyrings/nv-tensorrt-local-2B368663-keyring.gpg] file:///var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8 /
    
    所以,我现在可以一个个的去安装这些本地的包了。难怪!然后我一股脑的安装了所有的包:
    
    sudo apt install /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/*.deb
    

四月八日 等待变化等待机会

  1. 什么是知识的储备呢?就是说一些本来应该是早就解决的问题不应该在多少年的使用中司空见惯而不去细究导致在随后的某一个行动中导致卡壳的疑问。这些都是早就该解决的问题:什么是deb文件?
    1. 首先它是一个压缩文件
      
      file /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/tensorrt-libs_10.0.0.6-1+cuda11.8_amd64.deb
      /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/tensorrt-libs_10.0.0.6-1+cuda11.8_amd64.deb: Debian binary package (format 2.0), with control.tar.xz, data compression xz
      
    2. 怎么解压缩呢?我像当然的人为xz就用xz来解压缩,但是不行,需要
      
      ar x /var/nv-tensorrt-local-repo-ubuntu2204-10.0.0-cuda-11.8/tensorrt-libs_10.0.0.6-1+cuda11.8_amd64.deb
      
      我们会好无例外的得到这么几个文件:control.tar.xz data.tar.xz debian-binary _gpgbuilder
    3. 这个解开的control包含什么内容呢?
      
      Package: tensorrt-libs
      Source: tensorrt
      Version: 10.0.0.6-1+cuda11.8
      Architecture: amd64
      Maintainer: cudatools <cudatools@nvidia.com>
      Installed-Size: 8
      Depends: libnvinfer10 (= 10.0.0.6-1+cuda11.8), libnvinfer-lean10 (= 10.0.0.6-1+cuda11.8), libnvinfer-plugin10 (= 10.0.0.6-1+cuda11.8), libnvinfer-vc-plugin10 (= 10.0.0.6-1+cuda11.8), libnvinfer-dispatch10 (= 10.0.0.6-1+cuda11.8), libnvonnxparsers10 (= 10.0.0.6-1+cuda11.8)
      Section: multiverse/devel
      Priority: optional
      Description: Meta package for TensorRT runtime libraries
       Meta package for TensorRT runtime libraries.
      
      这里就是我不明白的地方了,这个是NVidia的众多的子package的一个,那么它是无名的吗?它们有一个共同的Packages文件里倒是列表了这些关系,问题是我怎么安装呢?。但是最根本的问题是这些头文件包里并没有给我惹麻烦的NvUtils.h的问题。
    且慢,我昨天遇到的问题是两个完全不同的问题,我现在才有些理解了:gcc遇到的问题看来是tensorflow已经在新版本不支持了,因为有大量的包的安装或者什么原因,所以,我编译的时候遇到这个NvUtils.h头文件找不到。但是clang的问题根本就是clang自己安装的问题,比如说我任意编译一个包含c++头文件#include <string>这样子的文件就会报出来找不到的问题,这个我以前是知道的,后来忘记了!但是我现在看到的似乎都不是我以前的解决 方法,而且似乎都不行! 比如我们看到gcc的搜索路径是
    
    #include "..." search starts here:
    #include <...> search starts here:
     /usr/include/c++/11
     /usr/include/x86_64-linux-gnu/c++/11
     /usr/include/c++/11/backward
     /usr/lib/gcc/x86_64-linux-gnu/11/include
     /usr/local/include
     /usr/include/x86_64-linux-gnu
     /usr/include
    End of search list.
    
    而clang的搜索路径漏掉了第一个
    
    #include "..." search starts here:
    #include <...> search starts here:
     /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++
     /usr/lib/llvm-15/lib/clang/15.0.7/include
     /usr/local/include
     /usr/include/x86_64-linux-gnu
     /usr/include
    End of search list.
    
    我隐约记得我原来是遇到这个问题,看来没有记录下来,现在要记下来!就是clang无法找到最基本的c++的头文件,因为它们并不是普通的头文件,而是一种高级的没有后缀名的头文件,比如string这个文件,对于gcc来说它是定义在 /usr/include/c++/11/string 这里还有一个关于#pragma GCC system_header的解释就是压制警告信息。
    The header files declaring interfaces to the operating system and runtime libraries often cannot be written in strictly conforming C. Therefore, GCC gives code found in system headers special treatment. All warnings, other than those generated by ‘#warning’ (see Diagnostics), are suppressed while GCC is processing a system header.
    而这个文件和clang找到的完全不一样这个需要clang添加参数-stdlib=libc++,而它是这个/usr/bin/../include/c++/v1/string 就是说目前我的系统不支持-stdlib=libstdc++,至少这个是由编译clang的时候决定的。gcc的这个string文件应该是所谓的stdc++一个头文件,它有一大堆的所谓的bits目录下的实现头文件。而与之相对比的libc++的是一个直接使用模板实现的完全的实现。
  2. 我当初在读gcc/clang文档的时候就没有搞懂这两者的区别。原来原因竟然是这么个狗皮许可证问题

    libstdc++ is the GNU c++ standard library implementation.

    libc++ is the LLVM/clang c++ standard library implementation.

    Even when compiling with clang, libstdc++ (gnu) is often used (on Linux).

    A main reason libc++ (clang) exists is that libstdc++ (gnu) is GPL and so Apple can't ship it, so you can think of libc++ as the non-GPL libstdc++.

  3. 我现在终于知道为什么,至少是部分知道,clang的问题了:
    1. clang的libstdc++的搜索路径不全,比如gcc的搜索路径是 /usr/include/c++/11 有一个版本号11,而当我使用clang -stdlib=libstdc++的时候得到的是
      
      nick@nick-sager:~$ realpath /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++
      /usr/include/c++
      
      而这里有个问题就是
      
      nick@nick-sager:~$ ls /usr/include/c++
      11  v1
      
      就是说也许是我的gcc-12的安装有些问题,或者是clang查询到的路径有问题,这里必须指定11,因为v1是libc++的实现,它们都在 /usr/include/c++是等效的实现,那么clang是如何获得gcc的libstdc++的路径的呢?
    2. 我找到以前的笔记,我曾经是直接使用clang的cc1来查看它的路径搜索的,不过这个-cc1似乎是没有更多的帮助,还是直接使用clang -c -v /tmp/test.cpp看到更多的细节
      
      (in-process)
       "/usr/bin/clang-17" -cc1 -triple x86_64-unknown-linux-gnu -emit-obj -mrelax-all -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name test.cpp -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -v -fcoverage-compilation-dir=/home/nick/diabloforum -resource-dir /usr/lib/clang/17 -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++ -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/x86_64-linux-gnu -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/backward -internal-isystem /usr/lib/clang/17/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdeprecated-macro -fdebug-compilation-dir=/home/nick/diabloforum -ferror-limit 19 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -fcolor-diagnostics -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o test.o -x c++ /tmp/test.cpp
      
      这里都是这些-internal-isystem得到的路径,这里 所以,这个-internal-isystem是谁i加给cc1才是最最需要搞清楚的。但是似乎这个clang的内部文档没有很简单的透露这个,这个部分从来就不是一个很标准的代码,因为往往和一些平台相关的很无理的实现。
    但是这个问题真的很难吗?我发现要么是ubuntu把包的名字改掉了,我发现它应该是libstdc++-12-dev。所以,如果我们默认clang是使用libc++而这个是混蛋的许可证问题苹果作出的决定,那么就要默认使用gcc的自带的libstdc++的话,就会遇到究竟采用哪一个gcc的版本,clang会挑选最高的版本,问题是这个对于gcc来说是自带的默认的,而clang需要额外的安装这个开发包,比如gcc-12版本的开发包就是libstdc++-12-dev!!!真的是瞎折腾!
  4. 这里有一个令人敬畏的帖子我需要仔细阅读。就是详细的编译clang的步骤,看来我又要回头来自己编译clang了吗?
  5. clang的问题解决了,我几乎就是身心疲惫,然后又遇到了最早的问题,就是gcc更早暴露的问题:
    
    cp: cannot stat '/usr/include/x86_64-linux-gnu/NvUtils.h': No such file or directory
    
    所以,这个才是根源?这个是大家都知道的问题了。
    
    $ dpkg -S NvInferPlugin.h
    libnvinfer-plugin-dev: /usr/include/x86_64-linux-gnu/NvInferPlugin.h
    $ sudo apt install libnvinfer-plugin-dev
    
    眼花了,根本是不同的文件! 我能找到最接近的问题应该是这里。我太累了!

四月九日 等待变化等待机会

  1. 偶然搜到Linux From Scratch,这个真是令人怀念的岁月啊,什么时候重温一下旧时的梦想?
  2. 我冷静了一下理了一下思路发现必须要踏踏实实学习一些基础知识,而熟悉掌握一些应用tensorflow是一个不错的选择,尤其先从它的应用着手是正确的选择,不要一开始就好高骛远,这个大量的论文应用模型就是一个很好的入手。
  3. tensorflow是有官方模型相联系的。这个是安装指南 我目前是安装了2.16版本,
    
    pip3 install tf-models-official==2.16
    
    小的release没有相应的模型版本号,就是说2.16.0是没有必要的,只要2.16就可以了。
  4. 这个不明觉厉的介绍让我看的晕晕乎乎。它的目的是什么呢?似乎它是这个标准文档的镜像
    BERT (Pre-training of Deep Bidirectional Transformers for Language Understanding) introduced the method of pre-training language representations on a large text corpus and then using that model for downstream NLP tasks.
    就是说BERT可以预训练语言模型,这个应该是我目前应该熟悉的部分。
    The nlp.networks.BertEncoder class implements the Transformer-based encoder as described in BERT paper. It includes the embedding lookups and transformer layers (nlp.layers.TransformerEncoderBlock), but not the masked language model or classification task networks.
    这个不就是我现在读论文感到有些不明所以然的部分吗?就是这个预训练的语言模型在Transformer的架构里作为一个encoder的角色出现来实现word embedding生成查找的功能,至于后面的mask部分我还是不明白,至少目前读的论文没有介绍到?
  5. 我开始有点感觉这个Model Garden for TensorFlow。架构和模型是紧密相联系的,工具怎么使用确实是一个大学问。
  6. 我之前没有下载过BER论文吗?
  7. 补课一个概念General Language Understanding Evaluation (GLUE) ,而这个wiki的大表非常的让我印象深刻!目前人工智能的发展是多么的兴旺与广泛啊!而这里仅仅是所谓的datasets这个是一个什么概念呢?
  8. 偶然搜到这个debootstrap ubuntu的帖子,它提到它的源头是这里这里。而官方的帮助我很久以前读过再复习一下。
  9. 我准备做一个实验,同时也是把一些命令写下来,用过无数次却都忘记了!
    1. 创建一个5G的文件。
      
      dd if=/dev/zero of=ubuntu-disk bs=1M count=5000
      
    2. 把它做成ext3文件系统
      
      mkfs -t ext3 ubuntu-disk 
      
    3. mount这个文件系统
      
      mkdir mnt
      sudo mount -o loop ubuntu-disk mnt/
      
    4. 使用debootstrap来创建ubuntu 22.04,参考部分这里的做法,其实大侠的问题很复杂,我根本看不大懂,因为他似乎要加密的安装?
      
      sudo apt install debootstrap
      sudo debootstrap focaljammy ./mnt https://mirror.leaseweb.com/ubuntu/
      
      这里后来我才发现我拷贝粘贴别人的命令安装的是20.04而不是22.04因为代号应该是jammy而不是focal。怎么办?升级吧反正是实验,因为是arch-chroot不用担心搞坏母系统。我看到很多人都是用这个do-release-upgrade来升级的。这个是在arch-chroot里面看到的arch-chroot的mount的环境,我估计我如果使用纯粹的chroot就要做这些个bind之类的,很麻烦。
      
      root@nick-sager:/# mount
      /home/nick/workspace/debootstrap/ubuntu-disk on / type ext3 (rw,relatime)
      proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
      sys on /sys type sysfs (ro,nosuid,nodev,noexec,relatime)
      efivarfs on /sys/firmware/efi/efivars type efivarfs (rw,nosuid,nodev,noexec,relatime)
      udev on /dev type devtmpfs (rw,nosuid,relatime,size=32733676k,nr_inodes=8183419,mode=755,inode64)
      devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000)
      shm on /dev/shm type tmpfs (rw,nosuid,nodev,relatime,inode64)
      tmpfs on /run type tmpfs (rw,nosuid,nodev,noexec,relatime,size=6554832k,mode=755,inode64)
      tmp on /tmp type tmpfs (rw,nosuid,nodev,inode64)
      tmpfs on /run/systemd/resolve/stub-resolv.conf type tmpfs (rw,nosuid,nodev,noexec,relatime,size=6554832k,mode=755,inode64)
      
    5. 然后我决定使用这个比通常的chroot高级的
      
      sudo arch-chroot ./mnt
      
    6. 我觉得第一件事情应该是设置时区语言等等,汉字是zh_CN.utf8。我怎么知道我当前的键盘是怎样的呢?这个好像是安装系统第一件需要人为设置的,因为无法自动识别。所以,这个文件记录的是我当前的键盘/etc/default/keyboard
      
      dpkg-reconfigure tzdata
      dpkg-reconfigure locales
      dpkg-reconfigure keyboard-configuration
      
    7. 启动如何安装呢?
      
      apt install grub-efi-amd64
      
      但是这里我是不敢安装bootloader,因为怕搞坏我的系统,显然这个是不能启动的:
      
      qemu-system-x86_64 -hda ubuntu-disk -m 2G
      
      所以,这里就是一个悖论,bootloader是实际媒介的启动,如何在虚拟的介质安装呢?我没有实际的分区来安装啊?其实这个不仅仅是一个好奇的想法,事实上是有实际用途的,这里解说的就是不贸然升级系统的解决方案。从这里也看出来如果你使用老式的chroot你要自己手动的bind这些设备/dev,/dev/pts,proc,sysfs
      
      sudo mount --bind /dev /mnt/installer/dev
      sudo mount --bind /dev/pts /mnt/installer/dev/pts
      sudo mount -t proc proc /mnt/installer/proc
      sudo mount -t sysfs sys /mnt/installer/sys
      sudo chroot /mnt/installer
      
      从这里看出来arch-chroot就都替你做了。
    8. 而安装内核,可以指定需要安装的ubuntu对应的版本
      
      apt install --no-install-recommends \
        linux-{,image-,headers-}generic-hwe-22.04 \
        linux-firmware initramfs-tools efibootmgr
      
      否则安装一般性的grub-pc linux-image是被问什么版本的,因为linux-image是一个虚拟的包。这里的这位大侠做的似乎是我需要的。不过我还是需要进一步的实验。总之我是完全的老糊涂了,第一步需要先把虚拟盘bootable
      
      fdisk mnt
      
      需要创建新的分区n,然后设置dos bootable。这里有极大可能是我要寻找的但是我非常的担心这个危险的操作,肯定要确保完全理解的前提下才能尝试,否则就是大灾难。总之原理是对的,就是要安装grub在一个loop device上,但是其中的细节至关重要我还没有掌握。
    9. 我确实是老糊涂了,我之前直接把我的image就是ext3方式mount在了mnt目录,那么我一直却觉得我是loop mount的,比如mount -t ext3 ubuntu-disk mnt,可是这个对于chroot是足够但是我现在需要安装grub的话,那就必须使用loop device
      
      sudo mount -o loop ubuntu-disk mnt
      
      可以事先使用losetup -f来发现第一个空闲的loop number,但是这个总是不十分稳妥的,还是事后查看来确定loop device。
      
      losetup -l | grep ubuntu-disk | cut -d' ' -f1
      
      这位大师是专业的,非常的严谨有各种各样的检验,而且考虑的是更加复杂的多个分区的情况,对于我仅仅是玩一下而已。
    10. 但是grub target有这么多选择
      --target=TARGET

      install GRUB for TARGET platform [default=x86_64-efi]; available targets: arm-coreboot, arm-efi, arm-uboot, arm64-efi, i386-coreboot, i386-efi, i386-ieee1275, i386-multiboot, i386-pc, i386-qemu, i386-xen, i386-xen_pvh, ia64-efi, loongarch64-efi, mips-arc, mips-qemu_mips, mipsel-arc, mipsel-loongson, mipsel-qemu_mips, powerpc-ieee1275, riscv32-efi, riscv64-efi, sparc64-ieee1275, x86_64-efi, x86_64-xen

      我最后尝试使用古老的i386-pc,但是遇到grub拒绝,于是只能硬来
      
      sudo grub-install --target=i386-pc --force --boot-directory=mnt/boot /dev/$(losetup -l | grep ubuntu-disk | cut -d' ' -f1)
      
    11. 然后我们来检验一下
      
      qemu-system-x86_64 -hda ubuntu-disk -m 2G
      
      不行!彻底的失败!这个是不对的!不能启动!而且我的鼠标被困住了,需要CTRL+ALT+G,因为我是GTK的前端。为了这个所谓的键盘特效,我才意识到<kbd>根本是一个仅仅表意的tag,需要自己设定css style,我特意加了一个box-shadow: 10px 5px 5px black;
    12. 我终于有一点点头绪了,就是我要事先创建EFI的partition,之前我一直拒绝想要使用古老的i386-pc,但是似乎很多毛病,也许需要ext2?太累了。
    13. 中午吃饭前活动了一下脑子有些清醒了,实际上所谓的EFI分区就是说我们要把UEFI的那些可以boot的binary文件放在那里,为什么呢?我以为是因为这个是通用的,也就是说windows/linux等等都要能够识别的文件系统,为了牵制只能选择windows的,所以,只是为了存放那些binary而已,并不是为了启动的其他原因,那么我就使用fdisk把之前的image文件硬硬的切割了一块下来,这个当然是非常的冒险,好在这个是实验而且是一个文件也没有什么大不了的,估计大部分都是空的,然后n(new)了一个FAT32/Win95(0b)的分区。这些做完了我就遇到我之前反复遇到的问题,我一直不知道有什么好的办法,就是说对于这个mulitiple的partition的image,正常的loop mount不能识别,最早我是借助于手动计算偏移非常的麻烦,现在才知道可以直接使用losetup的-Pf选项:
      
      sudo losetup -Pf ubuntu-disk
      $ ll $(losetup -l | grep ubuntu-disk| cut -d' ' -f1)*
      brw-rw---- 1 root disk   7, 9 Apr 10 11:38 /dev/loop9
      brw-rw---- 1 root disk 259, 7 Apr 10 11:38 /dev/loop9p1
      brw-rw---- 1 root disk 259, 8 Apr 10 11:38 /dev/loop9p2
      

四月十一日 等待变化等待机会

  1. 我参考以前的image,发现它是这样子的
    
    nick@nick-sager:~/ami$ sudo fdisk -l serverdisk.img 
    Disk serverdisk.img: 10 GiB, 10737418240 bytes, 20971520 sectors
    Units: sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disklabel type: gpt
    Disk identifier: 49FC2B67-59F5-4FCC-B556-CC70715F2FCE
    
    Device          Start      End  Sectors Size Type
    serverdisk.img1  2048     4095     2048   1M BIOS boot
    serverdisk.img2  4096 20969471 20965376  10G Linux filesystem
    
    这里的BIOS boot据说并不是文件系统,而是所谓的
    A BIOS boot partition doesn't contain a filesystem; it's just a place to put some GRUB code that on an MBR disk would've been located immediately after the boot sector, before the start of the first partition. On a GPT disk, that area is used by the (larger) partition table and isn't available for bootloader code, so the bootloader code goes in a small partition instead.
    这个是我依稀记得的。让我看看实际的结果吧:使用fdisk选择第一个partition然后使用i查看信息:
    
             Device: serverdisk.img1
              Start: 2048
                End: 4095
            Sectors: 2048
               Size: 1M
               Type: BIOS boot
          Type-UUID: 21686148-6449-6E6F-744E-656564454649
               UUID: F9AA3449-71BC-4D24-959B-D1DE8D0F8C5B
    
    注意它的起始依然是2048*512=1024*1024=1M,我依稀记得GPT的启动部分是兼容MBR的吧?MBR是512能被包含在这个1M里?
  2. 所以,我重新制作我的image:
    1. 第一步依然是
      dd if=/dev/zero of=ubuntu-disk bs=1M count=5000
    2. 然后使用fdisk制作两个分区:第一个是代号4的BIOS boot,大小为1M;第二个才是其余的全部。整个使用GPT分区方式。
    3. 使用losetup -Pf来mount
      
      sudo losetup -Pf --show ubuntu-disk
      
      这样子可以获得loop的号码,查看可以看到有两个partiton的mount。第二个是我们需要的。
    4. 针对第二个partition制作文件系统:
      
      dev=$(losetup -l | grep ubuntu-disk | cut -d' ' -f1)
      sudo mke2fs -t ext4 ${dev}p2
      
      相应的对于第一个BIOS boot分区我做成vfat
      
      dev=$(losetup -l | grep ubuntu-disk | cut -d' ' -f1)
      sudo mkfs.vfat -F 32 ${dev}p1
      
    5. 创建mount point并且mount
      
      mkdir -p linux efi
      dev=$(losetup -l | grep ubuntu-disk | cut -d' ' -f1)
      sudo mount -t ext4 ${dev}p2 linux/
      sudo mount -t vfat ${dev}p1 efi
      
    6. 然后就是debootstrap来创建ubuntu,这里我使用官方的网站速度快得多。
      
      sudo debootstrap jammy linux/
      
    7. 如何配置呢?我这里参考一下这位大侠的做法,重要的是网络的设置部分,首先我是arch-chroot去安装必要的工具,就容易的多了。不过这里的网络设置似乎是没有用的,因为我的虚拟机似乎是不能够直接使用网卡的吧?所以,这里是一个接下去需要理解的部分。
      
      apt install vim
      apt update && apt upgrade -y
      apt install -y --no-install-recommends \
        linux-{,image-,headers-}generic linux-firmware \
        initramfs-tools cryptsetup{,-initramfs} efibootmgr
      dpkg-reconfigure tzdata
      dpkg-reconfigure locales
      dpkg-reconfigure keyboard-configuration
      echo "nick-emu" > /etc/hostname
      touch /etc/systemd/network/ethernet.network
      echo "[Match]
      Name=enp0s31f6
      [Network]
      DHCP=yes
      " > /etc/systemd/network/ethernet.network
      
      然后是安装grub,不要os-probe安装其他的系统。我这里选择使用grub-pc也就是i386纯粹为了简单。也就是说GPT是兼容MBR的启动的吧?所以,这个领域是我之前一直概念模糊的地方。
      
      apt install grub-pc
      echo "GRUB_DISABLE_OS_PROBER=false" >> /etc/default/grub
      dev=$(losetup -l | grep ubuntu-disk | cut -d' ' -f1)
      grub-install ${dev}
      
    8. 不要忘了设置登陆密码passwd
    9. 最后就是唤起虚拟机
      
      qemu-system-x86_64 -hda ubuntu-disk -m 4G
      
      这里我不用sudo就是为了安全,但是不知道这个会不会有什么其他的问题?网卡?看起来网络不是虚拟机本身的问题而是在qemu的外设配置吧?
    总而言之,总算第一步完成了,可以顺利制作一个虚拟磁盘并且启动了。
  3. 之前使用的是grub-pc创建的i386-pc目标,这个做法纯粹的是古老的模式,不是现在的UEFI,其实,压根没有必要创建单独的vfat分区。我打算重新做一个带有efi分区的支持UEFI启动的磁盘:
    1. 县创建5G的磁盘文件
      dd if=/dev/zero of=ubutnu-efi-disk bs=1M count=5000
    2. 我想尝试制作一个脚本来制作分区,保存这个手动得到脚本 这个是所有的partition type的表。
      
      $ sfdisk ubuntu-efi-disk > ubuntu-efi.script
      $ cat ubuntu-efi.script
      label: gpt
      label-id: 77615560-1E8B-724E-9415-2E9E25D1A687
      device: ubuntu-efi-disk
      unit: sectors
      first-lba: 2048
      last-lba: 10239966
      sector-size: 512
      
      ubuntu-efi-disk1 : start=        2048, size=     1048576, type=C12A7328-F81F-11D2-BA4B-00A0C93EC93B, uuid=B97AF9B8-AF27-784D-AA31-6C3A9CA9D2CD
      ubuntu-efi-disk2 : start=     1050624, size=     9189343, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=F5E033F5-DE64-CB4C-8899-E2AC39CE0935
      
      如果再次使用的话就是
      
      sfdisk ubuntu-efi-disk < ubuntu-efi.script
      
      但是这么做有些太危险了。主要是其中的uuid不应该被复用。。。
      
      fdisk -l ubuntu-efi-disk
      Disk ubuntu-efi-disk: 4.88 GiB, 5242880000 bytes, 10240000 sectors
      Units: sectors of 1 * 512 = 512 bytes
      Sector size (logical/physical): 512 bytes / 512 bytes
      I/O size (minimum/optimal): 512 bytes / 512 bytes
      Disklabel type: gpt
      Disk identifier: 77615560-1E8B-724E-9415-2E9E25D1A687
      
      Device             Start      End Sectors  Size Type
      ubuntu-efi-disk1    2048  1050623 1048576  512M EFI System
      ubuntu-efi-disk2 1050624 10239966 9189343  4.4G Linux filesystem
      
      总而言之,这个是结果。
    3. 然后依然使用losetup来loop mount这个image,这里--show记录下了loop设备。
      
      sudo losetup -Pf --show ubuntu-efi-disk
      
    4. 分别创建vfat和ext4文件系统
      
      dev=$(losetup -l | grep ubuntu-efi-disk | cut -d' ' -f1)
      sudo mkfs.vfat -F 32 ${dev}p1
      sudo mke2fs -t ext4 ${dev}p2
      
    5. 分别把两个分区都mount到efi和linux再去安装系统
      
      mkdir -p linux efi
      dev=$(losetup -l | grep ubuntu-efi-disk | cut -d' ' -f1)
      sudo mount -t vfat ${dev}p1 efi
      sudo mount -t ext4 ${dev}p2 linux
      
    6. 然后重复使用debootstrap创建ubuntu22.04
      
      sudo debootstrap jammy linux
      
      安装内核,因为debootstrap仅仅是帮你创建了linux的文件系统,必要的配置我觉得都可以省略因为反正boot以后也不能访问硬件?我应该尝试在qemu里配置?
    7. 这个就是我以前记忆中的debootstrap里的后半段,就是chroot去配置的部分,以前不理解为什么文件系统都有了还要chroot去安装,其实理论上debootstrap也可以把内核安装,可是这个根本就是多余,这个是linux的灵活之处,大多数人肯定是要定制化的。所以吃力不讨好。以前不知道有arch-chroot的好非常的辛苦。
      sudo arch-chroot linux
      配置安装内核和昨天是一样的。
      
      apt install --no-install-recommends \
        linux-{,image-,headers-}generic-hwe-22.04 \
        linux-firmware initramfs-tools efibootmgr
      apt install grub-efi
      
    8. 这里我们将对这个磁盘镜像安装efi-grub,这里的efi实际上是一个efi的分区的mount point
      
      sudo grub-install --target=x86_64-efi --boot-directory=linux/boot --efi-directory=efi ${dev}
      
      结果是怎么样子的呢?
      这里是boot/grub目录下安装的情况
      
      $ sudo tree linux/boot/grub
      locales-launch: Data of en_US locale not found, generating, please wait...
      linux/boot/grub
      ├── fonts
      │   └── unicode.pf2
      ├── grubenv
      ├── locale
      │   ├── en_AU.mo
      │   ├── en_CA.mo
      │   ├── en_GB.mo
      │   ├── en@quot.mo
      │   └── zh_CN.mo
      └── x86_64-efi
          ├── acpi.mod
          ├── adler32.mod
          ├── affs.mod
          ├── afs.mod
          ├── afsplitter.mod
          ├── ahci.mod
          ├── all_video.mod
          ├── aout.mod
          ├── appleldr.mod
          ├── archelp.mod
          ├── ata.mod
          ├── at_keyboard.mod
          ├── backtrace.mod
          ├── bfs.mod
          ├── bitmap.mod
          ├── bitmap_scale.mod
          ├── blocklist.mod
          ├── boot.mod
          ├── bsd.mod
          ├── bswap_test.mod
          ├── btrfs.mod
          ├── bufio.mod
          ├── cat.mod
          ├── cbfs.mod
          ├── cbls.mod
          ├── cbmemc.mod
          ├── cbtable.mod
          ├── cbtime.mod
          ├── chain.mod
          ├── cmdline_cat_test.mod
          ├── cmp.mod
          ├── cmp_test.mod
          ├── command.lst
          ├── configfile.mod
          ├── core.efi
          ├── cpio_be.mod
          ├── cpio.mod
          ├── cpuid.mod
          ├── crc64.mod
          ├── cryptodisk.mod
          ├── crypto.lst
          ├── crypto.mod
          ├── cs5536.mod
          ├── ctz_test.mod
          ├── datehook.mod
          ├── date.mod
          ├── datetime.mod
          ├── diskfilter.mod
          ├── disk.mod
          ├── div.mod
          ├── div_test.mod
          ├── dm_nv.mod
          ├── echo.mod
          ├── efifwsetup.mod
          ├── efi_gop.mod
          ├── efinet.mod
          ├── efi_uga.mod
          ├── ehci.mod
          ├── elf.mod
          ├── eval.mod
          ├── exfat.mod
          ├── exfctest.mod
          ├── ext2.mod
          ├── extcmd.mod
          ├── f2fs.mod
          ├── fat.mod
          ├── file.mod
          ├── fixvideo.mod
          ├── font.mod
          ├── fshelp.mod
          ├── fs.lst
          ├── functional_test.mod
          ├── gcry_arcfour.mod
          ├── gcry_blowfish.mod
          ├── gcry_camellia.mod
          ├── gcry_cast5.mod
          ├── gcry_crc.mod
          ├── gcry_des.mod
          ├── gcry_dsa.mod
          ├── gcry_idea.mod
          ├── gcry_md4.mod
          ├── gcry_md5.mod
          ├── gcry_rfc2268.mod
          ├── gcry_rijndael.mod
          ├── gcry_rmd160.mod
          ├── gcry_rsa.mod
          ├── gcry_seed.mod
          ├── gcry_serpent.mod
          ├── gcry_sha1.mod
          ├── gcry_sha256.mod
          ├── gcry_sha512.mod
          ├── gcry_tiger.mod
          ├── gcry_twofish.mod
          ├── gcry_whirlpool.mod
          ├── geli.mod
          ├── gettext.mod
          ├── gfxmenu.mod
          ├── gfxterm_background.mod
          ├── gfxterm_menu.mod
          ├── gfxterm.mod
          ├── gptsync.mod
          ├── grub.efi
          ├── gzio.mod
          ├── halt.mod
          ├── hashsum.mod
          ├── hdparm.mod
          ├── hello.mod
          ├── help.mod
          ├── hexdump.mod
          ├── hfs.mod
          ├── hfspluscomp.mod
          ├── hfsplus.mod
          ├── http.mod
          ├── iorw.mod
          ├── iso9660.mod
          ├── jfs.mod
          ├── jpeg.mod
          ├── json.mod
          ├── keylayouts.mod
          ├── keystatus.mod
          ├── ldm.mod
          ├── legacycfg.mod
          ├── legacy_password_test.mod
          ├── linux16.mod
          ├── linuxefi.mod
          ├── linux.mod
          ├── loadbios.mod
          ├── load.cfg
          ├── loadenv.mod
          ├── loopback.mod
          ├── lsacpi.mod
          ├── lsefimmap.mod
          ├── lsefi.mod
          ├── lsefisystab.mod
          ├── lsmmap.mod
          ├── ls.mod
          ├── lspci.mod
          ├── lssal.mod
          ├── luks2.mod
          ├── luks.mod
          ├── lvm.mod
          ├── lzopio.mod
          ├── macbless.mod
          ├── macho.mod
          ├── mdraid09_be.mod
          ├── mdraid09.mod
          ├── mdraid1x.mod
          ├── memdisk.mod
          ├── memrw.mod
          ├── minicmd.mod
          ├── minix2_be.mod
          ├── minix2.mod
          ├── minix3_be.mod
          ├── minix3.mod
          ├── minix_be.mod
          ├── minix.mod
          ├── mmap.mod
          ├── moddep.lst
          ├── modinfo.sh
          ├── morse.mod
          ├── mpi.mod
          ├── msdospart.mod
          ├── mul_test.mod
          ├── multiboot2.mod
          ├── multiboot.mod
          ├── nativedisk.mod
          ├── net.mod
          ├── newc.mod
          ├── nilfs2.mod
          ├── normal.mod
          ├── ntfscomp.mod
          ├── ntfs.mod
          ├── odc.mod
          ├── offsetio.mod
          ├── ohci.mod
          ├── part_acorn.mod
          ├── part_amiga.mod
          ├── part_apple.mod
          ├── part_bsd.mod
          ├── part_dfly.mod
          ├── part_dvh.mod
          ├── part_gpt.mod
          ├── partmap.lst
          ├── part_msdos.mod
          ├── part_plan.mod
          ├── part_sun.mod
          ├── part_sunpc.mod
          ├── parttool.lst
          ├── parttool.mod
          ├── password.mod
          ├── password_pbkdf2.mod
          ├── pata.mod
          ├── pbkdf2.mod
          ├── pbkdf2_test.mod
          ├── pcidump.mod
          ├── pgp.mod
          ├── play.mod
          ├── png.mod
          ├── priority_queue.mod
          ├── probe.mod
          ├── procfs.mod
          ├── progress.mod
          ├── raid5rec.mod
          ├── raid6rec.mod
          ├── random.mod
          ├── rdmsr.mod
          ├── read.mod
          ├── reboot.mod
          ├── regexp.mod
          ├── reiserfs.mod
          ├── relocator.mod
          ├── romfs.mod
          ├── scsi.mod
          ├── search_fs_file.mod
          ├── search_fs_uuid.mod
          ├── search_label.mod
          ├── search.mod
          ├── serial.mod
          ├── setjmp.mod
          ├── setjmp_test.mod
          ├── setpci.mod
          ├── sfs.mod
          ├── shift_test.mod
          ├── signature_test.mod
          ├── sleep.mod
          ├── sleep_test.mod
          ├── smbios.mod
          ├── spkmodem.mod
          ├── squash4.mod
          ├── strtoull_test.mod
          ├── syslinuxcfg.mod
          ├── tar.mod
          ├── terminal.lst
          ├── terminal.mod
          ├── terminfo.mod
          ├── test_blockarg.mod
          ├── testload.mod
          ├── test.mod
          ├── testspeed.mod
          ├── tftp.mod
          ├── tga.mod
          ├── time.mod
          ├── tpm.mod
          ├── trig.mod
          ├── tr.mod
          ├── true.mod
          ├── udf.mod
          ├── ufs1_be.mod
          ├── ufs1.mod
          ├── ufs2.mod
          ├── uhci.mod
          ├── usb_keyboard.mod
          ├── usb.mod
          ├── usbms.mod
          ├── usbserial_common.mod
          ├── usbserial_ftdi.mod
          ├── usbserial_pl2303.mod
          ├── usbserial_usbdebug.mod
          ├── usbtest.mod
          ├── video_bochs.mod
          ├── video_cirrus.mod
          ├── video_colors.mod
          ├── video_fb.mod
          ├── videoinfo.mod
          ├── video.lst
          ├── video.mod
          ├── videotest_checksum.mod
          ├── videotest.mod
          ├── wrmsr.mod
          ├── xfs.mod
          ├── xnu.mod
          ├── xnu_uuid.mod
          ├── xnu_uuid_test.mod
          ├── xzio.mod
          ├── zfscrypt.mod
          ├── zfsinfo.mod
          ├── zfs.mod
          └── zstd.mod
      
      3 directories, 285 files
      
      而efi分区下的结果就简单的多了
      
      $ sudo tree efi/
      efi/
      └── EFI
          ├── BOOT
          │   ├── BOOTX64.EFI
          │   ├── fbx64.efi
          │   └── mmx64.efi
          └── ubuntu
              ├── BOOTX64.CSV
              ├── grub.cfg
              ├── grubx64.efi
              ├── mmx64.efi
              └── shimx64.efi
      
      3 directories, 8 files
      
      这里要明白一点,就是grub仅仅是安装和设置,真正起作用配置启动是要在update-grub脚本执行的时候,现在先把os-probe禁止掉。这里我才意识到我还是要在镜像里安装grub,否则怎么执行update-grub呢?
      
      $ sudo arch-chroot linux
      $ apt install grub-common
      $ echo "GRUB_DISABLE_OS_PROBER=true"  >> /etc/default/grub
      
    9. 然后我们来检验一下是否能够启动
      
      qemu-system-x86_64 -hda ubuntu-efi-disk -m 4G
      
      失败!!!看来有什么地方做的不对!我尝试在fdisk里进入所谓的hybrid的MBR子菜单toggle boot flag,也不行。 虽然失败了,但是我发现有一个更加安全的做法,就是在arch-chroot里安装grub后执行grub-install之前,把efi的loop mount到/boot/efi目录,这个是默认的目录,就可以了。但是无论如何efi的制作应该是有什么关节没有打通。
  4. 总而言之,目前我只能制作i386的MBR或者GPT的磁盘镜像文件。
  5. 我回过头来总结发现其实之前的做法有很多问题
    1. 我如果是简单的MBR的启动完全不必创建多余的分区,也就是说不论GPT/MBR,我就只创建一个Linux分区,看来我是错的,因为如果我没有这个BIOS boot分区的话安装grub会报错this GPT partition label contains no BIOS Boot Partition; embedding won't be possible这里有着非常的详细的解释。而这个wiiki正是我这两天最需要阅读的部分。这个官方的称法是BIOS-based boot
      The BIOS boot partition is a partition on a data storage device that GNU GRUB uses on legacy BIOS-based personal computers in order to boot an operating system, when the actual boot device contains a GUID Partition Table (GPT). Such a layout is sometimes referred to as BIOS/GPT boot.
      这里解释了为什么GPT需要这个partition
      A BIOS boot partition is needed on GPT-partitioned storage devices to hold the second stages of GRUB. On traditional MBR-partitioned devices, the disk sectors immediately following the first are usually unused, as the partitioning scheme does not designate them for any special purpose and partitioning tools avoid them for alignment purposes. On GPT-based devices, the sectors hold the actual partition table, necessitating the use of an extra partition. On MBR-partitioned disks, boot loaders are usually implemented so the portion of their code stored within the MBR, which cannot hold more than 512 bytes, operates as a first stage that serves primarily to load a more sophisticated second stage, which is, for example, capable of reading and loading an operating system kernel from a file system.
      简而言之,MBR不需要的原因就是它的loader必须是小于512可以放在MBR结构里的,而GPT则不同,因为兼容512-byte-MBR的后面是真正的partition table,GPT这就要求有额外的空间。
    2. 关于second stage boot loader的储藏地MBR是在所谓的MBR gap,但是GPT只能另外做一个分区了。
      On MBR disks, such boot loaders typically use the sectors immediately following the MBR for this storage; that space is usually known as the "MBR gap". No equivalent unused space exists on GPT disks, and the BIOS boot partition is a way to officially allocate such space for use by the boot loader.
      所以,教训就是我必须要创建一个传统的dos disklabel?不能使用gpt。
      
      Disk ubuntu-disk: 4.88 GiB, 5242880000 bytes, 10240000 sectors
      Units: sectors of 1 * 512 = 512 bytes
      Sector size (logical/physical): 512 bytes / 512 bytes
      I/O size (minimum/optimal): 512 bytes / 512 bytes
      Disklabel type: dos
      Disk identifier: 0xed9152a5
      
      Device       Boot Start      End  Sectors  Size Id Type
      ubuntu-disk1 *     2048 10239999 10237952  4.9G 83 Linux
      
    3. 然后这个就是关键点,我看了很多文档就是没有理解这个偏移的问题。理论上我可以直接把这个文件mount,但是问题在于如果简单的mount它是从最开始起始的,那么随后创建文件系统等于是把分区表覆盖了,这里我们必须使用loop mount来控制偏移
      
      sudo losetup -Pf --show -o 1048576 ubuntu-disk
      
      这里的偏移1048576是怎么得来的呢?是在看到fdisk -l ubuntu-disk里的起始2048sector乘以sector size 512得来的。这个是我失败了好几次文件系统创建才明白的。这个是众多大神们反反复复提醒并且写脚本来防止这种错误的原因。但是我却无感,因为不理解。
    4. 然后我们再把这个loop mount,因为只有一个分区所以相对很简单了。接下去就是照旧使用debootstrap来创建文件系统,chroot安装内核,其实这个原本是debootstrap的second stage部分,只不过我们手动去做了。然后就是安装grub因为没有efi所以也变得很简单了。然后启动看看成功与否?实际上这个暴露了我最基本的概念的缺失,因为启动是一个针对实际物理环境的配置,你是无法预安装的,除非你预先知道运行的机器硬件信息,否则启动就是无意义的。而对于虚拟机本来就无所谓硬件信息,只要虚拟机主机来支持根本就不用考虑配置的问题。所以,这个纯粹是无稽之谈,最多可以作为模拟实验来学习研究。
    5. 这里就是一个非常微妙的地方,因为我为了对齐文件系统loop mount有偏移了1M,但是当我要安装grub的时候,我却必须使用一个完全的loop device来些MBR,所以,我就另外的loop mount了一个。
      
      sudo losetup -Pf --show ubuntu-disk
      
      这条路又失败了,就是说之前只有GPT/BIOS boot是成功的。
    6. 重新来过!我发现我目前只能做成GPT/BIOS的启动,肯定是哪里有做错了?
  6. 遇到了loop mount不能被detach的问题,这里有很多的讨论。这里提到的mtab和mounts都是软链接
    
    nick@nick-sager:~/workspace/debootstrap$ ll /etc/mtab
    lrwxrwxrwx 1 root root 19 Mar 31  2023 /etc/mtab -> ../proc/self/mounts
    nick@nick-sager:~/workspace/debootstrap$ ll /proc/mounts
    lrwxrwxrwx 1 root root 11 Apr  3 12:19 /proc/mounts -> self/mounts
    
    而这位大侠使用strace发现这个flag:LO_FLAGS_AUTOCLEAR没有正确的设定?
    
    strace -e trace=ioctl,mount mount -o loop /tmp/block.img /mnt/
    
  7. 我怀疑无法detach loop mount是因为在sidebar上有这个volume的显示
    
    gsettings set org.gnome.shell.extensions.dash-to-dock show-mounts false
    
    找了一圈才发现是我自己糊涂居然有一个mount没有umount,这个怪不得loop mount,内核做的是对的!

四月十二日 等待变化等待机会

  1. 我现在开始有些明白了,不论是哪种模式GRUB的bootloader都比较大是需要额外的空间的,这里的解说非常的细致。

    On an MSDOS partitioned disk, this location is typically stuck between partitions, not even in a filesystem.

    On a GPT partitioned disk, there is no room to shoehorn in the rest of the bootloader between partitions, so an explicit place needs to be made for the code -- an unformatted small partition (1MB-2MB) with the BIOS-GRUB flag.
    所以,我怀疑这个所谓的bootloader的区域压根就是存放二进制码根本就不需要文件系统,那么也无需创建,反正dos模式下就是紧挨着0 sector后面,那么对于GPT要明确一个partition,那么也是不需要文件系统来支持的。 那么EFI的分区是怎么样的呢?

    To boot in UEFI mode (assuming that capability in the hardware exists), either partition type needs an EFI partition with 1)a FAT filesystem, 2)the boot flag and 3)the ESP (EFI System Partition) flag.

    看来我可能是没有设定boot flag! 而这个最最基本的东西我十年前就在看还是老是忘记名词:
    The two major partitioning types of PC disks, GPT and MSDOS may each be used in either of two modes, UEFI or BIOS/legacy. Ubuntu may be installed on either partitioning type in either mode, but Windows 8/10 in UEFI mode requires GPT partitioning, and in legacy mode MSDOS partitioning.
    两种分区方式GPT和DOS,启动模式也是两种UEFI还是BIOS/legacy,这样子共有四种组合,ubuntu都没有问题,但是win8/10却要求必须是(UEFI/GPT),(DOS/BIOS)的组合两种。
  2. 其实,我现在认为我的错误就在于没有给grub-bootloader生存的空间,也就是说在GPT模式下要拿出大约!M的BIOS boot partition来让grub存放。这个我觉得即便是DOS模式下也是需要的,但是DOS没有明确要求就直接使用了第一个sector后面的空间,这个是投机取巧,但是为了让这个名正言顺起来,我们就人为的分配给它一个不用的分区让它自由自在的存。这个想法是错误的,我看看我自己的笔记本的分区是这样子的
    
    nick@nick-sager:~/workspace/debootstrap$ sudo fdisk -l /dev/nvme0n1
    Disk /dev/nvme0n1: 1.82 TiB, 2000398934016 bytes, 3907029168 sectors
    Disk model: WD Blue SN570 2TB                       
    Units: sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disklabel type: gpt
    Disk identifier: D107060B-0D72-4008-A966-22D0BE31C1FB
    
    Device           Start        End    Sectors  Size Type
    /dev/nvme0n1p1    2048    1050623    1048576  512M EFI System
    /dev/nvme0n1p2 1050624 3907028991 3905978368  1.8T Linux filesystem
    
    这里压根就不要有什么额外的boot bios分区,所以,要改!幸好fdisk有高级功能看能不能合并?
  3. 我发现fdisk有很多高级功能我以前不知道,比如可以使用fix partition order来解决合并删除分区后的空档。但这个都不是主要问题,最核心的问题是我创建了EFI分区是第一个分区,那么MBR要怎么办?我单纯的grub-install不会帮我处理MBR,我的理解是它还是要安装,但是问题是怎么做呢?如果我使用grub-pc的安装就会报错说是embedded不支持之类的,我理解这个是危险的因为grub会占用额外的空间要越界所以不肯这么做,但是我的MBR要怎么办呢?这里有一些关于bootloader的表有一点我现在是清楚了,就是安装grub一定要在chroot里做,这个是因为首先安全一些,其次你如果把EFI分区mount到了/boot/efi下的话,这根本就省却了额外的参数。而且你设定的禁止os-probe本来也是在虚拟机环境上的。当然你还是要使用根部的设备,这个就是losetup里的参数-Pf里的P的妙用,因为它是能够识别分区的loop mount,这个是非常的强大的!
  4. 与其胡乱的搜索不如去读标准,这个是UEFI的标准!我顺手保存了一份。 我觉得我还是很机智的,因为我们知道MBR是一定要设定,所以,我就先使用目标i386-pc把MBR强制写下,这里要用--force告诉grub-install我知道在干什么。然后再运行一遍使用--target=x86_64-efi,当然前提是我已经把efi分区mount在了/boot/efi目录下。那么我到底是怎么启动的呢?是MBR/DOS吗?应该不是,因为磁盘标志是GPT,那么它是怎么找到bootloader的呢?这个需要看UEFI的文档才能回答。
  5. 我觉得我已经找对了方向,其他都是细节的学习,因为有了UEFI的规范几乎一切都可以迎刃而解,至少我是这么乐观的。本来只是想快速的做个实验结果连续好几天都在折腾,不过收获满满的。先歇一歇吧!

四月十三日 等待变化等待机会

  1. 这个是摘抄的UEFI关于MBR的规范
    LBA 0 (i.e., the first logical block) of the hard disk contains either
    • a legacy Master Boot Record (MBR)
      Mnemonic Byte Offset Byte Length Description
      BootCode 0 424 x86 code used on a non-UEFI system to select an MBR partition record and load the first logical block of that partition . This code shall not be executed on UEFI systems.
      UniqueMBRDiskSignature 440 4 Unique Disk Signature This may be used by the OS to identify the disk from other disks in the system. This value is always written by the OS and is never written by EFI firmware.
      Unknown 444 2 Unknown. This field shall not be used by UEFI firmware.
      PartitionRecord 446 16*4 Array of four legacy MBR partition records (
      Signature 510 2 Set to 0xAA55 (i.e., byte 510 contains 0x55 and byte 511 contains 0xAA).
      Reserved 512 Logical BlockSize - 512 The rest of the logical block, if any, is reserved.
      The MBR contains four partition records that each define the beginning and ending LBAs that a partition consumes on a disk.
      Mnemonic Byte Offset Byte Length Description
      BootIndicator 0 1 0x80 indicates that this is the bootable legacy partition. Other values indicate that this is not a bootable legacy partition. This field shall not be used by UEFI firmware.
      StartingCHS 1 3 Start of partition in CHS address format. This field shall not be used by UEFI firmware.
      OSType 4 1 Type of partition.
      • 0xEF (i.e., UEFI System Partition) defines a UEFI system partition.
      • 0xEE (i.e., GPT Protective) is used by a protective MBR to define a fake partition covering the entire disk.
      EndingCHS 5 3 End of partition in CHS address format. This field shall not be used by UEFI firmware.
      StartingLBA 8 4 Starting LBA of the partition on the disk. This field is used by UEFI firmware to determine the start of the partition.
      SizeInLBA 12 4 Size of the partition in LBA units of logical blocks. This field is used by UEFI firmware to determine the size of the partition.
    • or a protective MBR
      Mnemonic Byte Offset Byte Length Contents
      Boot Code 0 440 Unused by UEFI systems. 所以,这里可以放空,反正UEFI不看!
      Unique MBR Disk Signature 440 4 Unused. Set to zero
      Unknown 444 2 Unused. Set to zero.
      Partition Record 446 16*4 Array of four MBR partition records. Contains:
      Signature 510 2 Set to 0xAA55 (i.e., byte 510 contains 0x55 and byte 511 contains 0xAA).
      Reserved 512 Logical Block Size - 512 The rest of the logical block, if any, is reserved. Set to zero.
      这个是专门针对Protective MBR的partition record table的规定。
      Mnemonic Byte Offset Byte Length Description
      BootIndicator 0 1 Set to 0x00 to indicate a non-bootable partition. If set to any value other than 0x00 the behavior of this flag on non-UEFI systems is undefined. Must be ignored by UEFI implementations.
      StartingCHS 1 3 Set to 0x000200, corresponding to the Starting LBA field.
      OSType 4 1 Set to 0xEE (i.e., GPT Protective)
      EndingCHS 5 3 Set to the CHS address of the last logical block on the disk. Set to 0xFFFFFF if it is not possible to represent the value in this field.
      StartingLBA 8 4 Set to 0x00000001 (i.e., the LBA of the GPT Partition Header).
      SizeInLBA 12 4 Set to the size of the disk minus one. Set to 0xFFFFFFFF if the size of the disk is too large to be represented in this field.
  2. 现在使用mc来查看我的MBR是否符合规范,这里的OS-type是不对的,这个当然是因为我使用i386-pc先做了一次写的MBR,后面的grub-efi是不会写这个的。这个难道是错误的流程吗?EFI难道不需要写MBR吗?那么就使用xxd来看看第一个partition record的情况吧
    
    nick@nick-sager:~/workspace/debootstrap$ xxd -d -s 446 -l 16 ubuntu-efi-disk 
    00000446: 0000 0200 eeff ffff 0100 0000 ff3f 9c00  .............?..
    
  3. 文档里有大量的UEFI的文献。这一篇是特别关于Partition Types: OS Type values used in the MBR disk layout,而我关心的是这个OS-type的标志量的列表
    • ee Indication that this legacy MBR is followed by an EFI header
    • ef Partition that contains an EFI file system

      Bob Griswold (rogris@Exchange.Microsoft.com) writes: MS plans on using EE and EF in the future for support of non-legacy BIOS booting. Mark Doran (mark.doran@intel.com) adds: these types are used to support the Extensible Firmware Interface specification (EFI); go to developer.intel.com and search for EFI. (For the types ee and ef, see Tables 16-6 and 16-7 of the EFI specification, EFISpec_091.pdf.)

    所以,如果不读原始文献我差点上当了,因为这里的解释差点让我误以为应该是EF而不是EE,现在看来EE是更加的合适。
  4. 为什么需要partition table呢?在我看来最直接的就是打破DOS的2GB限制。什么是protective MBR呢?就是说GPT的规范压根儿就把第一个sector也就是MBR部分留空了,这个是fdisk的说明部分
    Note that the first sector is still reserved for a protective MBR in the GPT specification. It prevents MBR-only partitioning tools from mis-recognizing and overwriting GPT disks.
    所以,当我看到fdisk打出的DISK LABEL如果是GPT就意味着MBR不应当被检查。其实,任何人都应该毫无困难的熟悉MBR的结构,因为就是一句话的事情:
    the structure of the MBR (Master Boot Record, sector 0) is as follows: First 446 bytes boot loader code, then 64 bytes partition table (starting at offset 0x1be = 446), finally 2 bytes signature 0xaa55.
    这里有各种各样的关于磁盘尺寸的限制的问题,我实在是没有心思看了,因为这些都是BIOS的问题吧?ATA/IDE磁盘我早都扔光了吧?
  5. 这位荷兰的老教授的个人网页有很多的有趣的东西,我似乎从来没有浏览过维基解密
  6. 我所怀疑的是不是我设置了类似于CSM的机制所以才能够在一个有问题的系统来启动呢?
    CSM boot requires a hard disk with MBR partition type, while UEFI boot mode requires a disk with the GPT partition table.
    不过看起来这个似乎是不可能的,就是说如果我使用了GPT,那么CSM(Compatibility Support Module)应该是不可能吧?不过我也不是很确定,如果我在开机的时候强制使用系统的BIOS启动模式会怎么样呢?我之前没有考虑过实际系统在开机时候是可以设置使用什么模式启动的选择,这个是人为决定的,那么qemu是怎么选择的呢? 我觉得wiki还是一个好东西,吃完早饭来看wiki关于UEFI的权威
    1. 我并不知道UEFI还有所谓的runtime service
    2. 什么是EFI system partition呢?
      An EFI system partition, often abbreviated to ESP, is a data storage device partition that is used in computers adhering to the UEFI specification. Accessed by the UEFI firmware when a computer is powered up, it stores UEFI applications and the files these applications need to run, including operating system boot loaders. Supported partition table schemes include MBR and GPT, as well as El Torito volumes on optical discs. For use on ESPs, UEFI defines a specific version of the FAT file system, which is maintained as part of the UEFI specification and independently from the original FAT specification, encompassing the FAT32, FAT16 and FAT12 file systems. The ESP also provides space for a boot sector as part of the backward BIOS compatibility.
      谁说UEFI不支持MBR?当然这个具体内涵是什么现在还不清楚。
    3. 具体是怎么样的呢?第一句就明确了UEFI根本不理会MBR,这个够明确了吧!但是,且慢,后面的所谓的boot manager是根据存在NVRAM里的参数来决定如何boot的。
      Unlike the legacy PC BIOS, UEFI does not rely on boot sectors, defining instead a boot manager as part of the UEFI specification. When a computer is powered on, the boot manager checks the boot configuration and, based on its settings, then executes the specified OS boot loader or operating system kernel (usually boot loader). The boot configuration is defined by variables stored in NVRAM, including variables that indicate the file system paths to OS loaders or OS kernels.
      我觉得接下来是关键:这里要求OS boot loader必须明确的被定义,在x86-64 system is \efi\boot\bootx64.efi,就是说这个是写死的,或者是默认的。
      Booting UEFI systems from GPT-partitioned disks is commonly called UEFI-GPT booting. Despite the fact that the UEFI specification requires MBR partition tables to be fully supported, some UEFI firmware implementations immediately switch to the BIOS-based CSM booting depending on the type of boot disk's partition table, effectively preventing UEFI booting to be performed from EFI System Partition on MBR-partitioned disks. Such a boot scheme is commonly called UEFI-MBR.
      这个也许就是微软为什么强调windows只支持UEFI-GPT或者BIOS-MBR的原因,如果分区是MBR,而且你也设置了EFI system partition,可是因为CSM模块设计就是要支持BIOS-MBR的启动,结果自然是直接就呼叫了BIOS-MBR的启动了,根本不看是否存在EFI system partition。到这里我算是初步明白为什么grub-efi对于MBR放空不写的原因了,就是不要给CSM机会,虽然这个可能性只是存在于BIOS-MBR,照例说UEFI-GPT应该是不可能调用CSM的。
    4. 这里非常的有必要把UEFI所心心念念的Protective MBRspec再看一下。所以,很清楚的就是我们只需要把MBR的第一个partition record和signature设定就可以了。这个需要做实验,于是我删除了假的MBR
      
      dd if=/dev/zero of=ubuntu-efi-disk bs=1 count=512
      
      我估计我这么干就把fdisk写上去的GPT信息也抹掉了吧?这么做太危险了!!! 然后chroot去安装grub-install遇到grub-install: error: cannot find a GRUB drive for /dev/loop5p1. Check your device.map.这里让我意识到我可以使用grub-mkdevicemap,但是查看之后
      
      root@nick-sager:/# cat /boot/grub/device.map 
      (hd0)	/dev/disk/by-id/nvme-WD_Blue_SN570_2TB_23032A802561
      (hd1)	/dev/disk/by-id/nvme-Fanxiang_S770M_4TB_FX232640342
      
      我决定使用自己手动创建的:
      
      root@nick-sager:/# cat /boot/grub/device.map 
      (hd0)	/dev/loop5
      
      当然这里的/dev/loop5是我当前loop mount的设备。决定再尝试安装grub
    5. 当我使用dd抹去MBR结果意外的也抹去了所有的GPT的信息,我只好重新进入fdisk创建一个空的GPT,这个是结果,就是说它会创建一个符合protective MBR的
      
      nick@nick-sager:~/workspace/debootstrap$ xxd -d -s 446 -l 16 ubuntu-efi-disk 
      00000446: 0000 0200 eeff ffff 0100 0000 07f0 8e00  ................
      
      完蛋了!我对于大侠的抹去MBR的做法是认可的,可是这么样使用dd,导致文件就只有512byte了,这个只能是使用在设备上!比如我loop mount的设备!!!这个实在是太可怕了!磁盘丢失只能重新来过了!
  7. 从头来过!
    1. 什么是创建一个空的GPT表呢?这个默认就是创建了一个所谓的protective MBR
      
      nick@nick-sager:~/workspace/debootstrap$ xxd -d -s 446 -l 16 ubuntu-efi-disk 
      00000446: 0000 0200 eeff ffff 0100 0000 ff3f 9c00  .............?..
      
      对比这个partition record表,就知道,标志是ee,同时最值得计算的是最后一个sizeInLBA是diskSize-1=0xff3f 9c00这个显然胡扯。
    2. 然后就是fdisk创建一个EFI system partion,大小512M,其余为一个Linux的分区。
    3. 使用losetup -Pf --show来mount这个磁盘文件,会根据分区自动产生连个子设备,然后分别制作文件系统mkfs.vfat -F 32,mkfs.ext4
    4. 然后使用debootstrap和arch-chroot来创建文件系统和内核以及安装工具包。
    5. 在安装完grub之后,我要手动创建所谓的device.map在/boot/grub/目录下。然后再去安装grub-install。
      
      root@nick-sager:/# cat /boot/grub/device.map
      (hd0)	/dev/loop5p1
      (hd1)	/dev/loop5p2
      
    不成功,我开始怀疑是不是qemu的参数有没有UEFI的选项?

四月十四日 等待变化等待机会

  1. 有必要学习GPT,因为我自认为对于MBR是很清楚了,虽然高级的extended部分还是不清楚,不过这个似乎是windows专属的吧我也不关心。
    Two GPT Header structures are stored on the device: the primary and the backup. The primary GPT Header must be located in LBA 1 (i.e., the second logical block), and the backup GPT Header must be located in the last LBA of the device.
    一头一尾两个就限制死了整个磁盘空间了。 关于GPT partition table其实也就是比较容易理解了,GPT表确实有点大,因为单单一个partition entry array就至少要16k,就是32个LBA(assume 512byte/LBA)
    The primary GPT Partition Entry Array must be located after the primary GPT Header and end before the First Usable LBA. The backup GPT Partition Entry Array must be located after the Last Usable LBA and end before the backup GPT Header.

    ...A minimum of 16,384 bytes of space must be reserved for the GPT Partition Entry Array.

    所以,这里的34就明白怎么来的吧?
    If the block size is 512, the First Usable LBA must be greater than or equal to 34 (allowing 1 block for the Protective MBR, 1 block for the Partition Table Header, and 32 blocks for the GPT Partition Entry Array); if the logical block size is 4096, the First Useable LBA must be greater than or equal to 6 (allowing 1 block for the Protective MBR, 1 block for the GPT Header, and 4 blocks for the GPT Partition Entry Array).
    这个让我想起来当年使用IPMI破解quanta的电源设备驱动dump出来的磁盘文件就是类似这个结构,就是说一个GPT的头部34k就是这么来的。 其实磁盘或者其他存储设备相当的复杂,因为物理的存储单元和逻辑的存储单元大小不是总是匹配的,因此分区要去对齐物理存储单元,这里还有所谓的SCSI设备的传输最小单元(optimal transfer length granularity),这些对齐的细节我就懒得了解了。 这里是GPT头的结构,摘抄一下吧。
    Mnemonic Byte Offset Byte Length Description
    Signature 0 8 Identifies EFI-compatible partition table header. This value must contain the ASCII string “EFI PART”, encoded as the 64-bit constant 0x5452415020494645.
    Revision 8 4 The revision number for this header. This revision value is not related to the UEFI Specification version. This header is version 1.0, so the correct value is 0x00010000.
    HeaderSize 12 4 Size in bytes of the GPT Header. The HeaderSize must be greater than or equal to 92 and must be less than or equal to the logical block size.
    HeaderCRC32 16 4 CRC32 checksum for the GPT Header structure. This value is computed by setting this field to 0, and computing the 32-bit CRC for HeaderSize bytes.
    Reserved 20 4 Must be zero.
    MyLBA 24 8 The LBA that contains this data structure.
    AlternateLBA 32 8 LBA address of the alternate GPT Header.
    FirstUsableLBA 40 8 The first usable logical block that may be used by a partition described by a GUID Partition Entry.
    DiskGUID 56 16 GUID that can be used to uniquely identify the disk.
    PartitionEntryLBA 72 8 The starting LBA of the GUID Partition Entry array.
    NumberOfPartitionEntries 80 4 The number of Partition Entries in the GUID Partition Entry array.
    SizeOfPartitionEntry 84 4 The size, in bytes, of each the GUID Partition Entry structures in the GUID Partition Entry array. This field shall be set to a value of 128 x 2n where n is an integer greater than or equal to zero (e.g., 128, 256, 512, etc.). NOTE: Previous versions of this specification allowed any multiple of 8..
    PartitionEntryArrayCRC32 88 4 The CRC32 of the GUID Partition Entry array. Starts at PartitionEntryLBA and is computed over a byte length of NumberOfPartitionEntries * SizeOfPartitionEntry.
    Reserved 92 BlockSize – 92 The rest of the block is reserved by UEFI and must be zero.
    1. 我专门检验了一下这个GPT的签名,因为我对于endian始终很不舒服,od似乎没有这么个显示的功能,它显示的是byte order
      
      nick@nick-sager:~/workspace/debootstrap$ od -j 512 -Ad -t x4  -N8 ubuntu-efi-disk 
      0000512 20494645 54524150
      0000520
      
      转而发现xxd可以显示little endian的方式来展现
      
      nick@nick-sager:~/workspace/debootstrap$ xxd -e -g8 -d -s 512 -l8 ubuntu-efi-disk 
      00000512: 5452415020494645                   EFI PART
      
    2. 我对于版本号也有些好奇:
      
      nick@nick-sager:~/workspace/debootstrap$ xxd -e -g4 -d -s 520 -l4 ubuntu-efi-disk 
      00000520: 00010000                             ....
      
      当然byte order是
      
      nick@nick-sager:~/workspace/debootstrap$ xxd -d -g1 -s 520 -l4 ubuntu-efi-disk 
      00000520: 00 00 01 00                                      ....
      
    3. GPT头的大小的确是92(0x5C)
      
      nick@nick-sager:~/workspace/debootstrap$ xxd -u -e -d -g4 -s 524 -l4 ubuntu-efi-disk 
      00000524: 0000005C                             \...
      
    4. 如果理解了就应该知道myLBA是1,因为对于GPT-header来说就是它自己的位置,那就是LBA-1在protective MBR后面。
      
      nick@nick-sager:~/workspace/debootstrap$ xxd -u -e -d -g8 -s 536 -l8 ubuntu-efi-disk 
      00000536: 0000000000000001                   ........
      
      尽信书不如不读书,如果你相信FirstUsableLBA是老老实实的最优化的第34个LBA那就天真了。实际上是2048,当然这个很有可能是我使用fdisk随手这么取默认值造成的。
      
      nick@nick-sager:~/workspace/debootstrap$ xxd -u -e -d -g8 -s 552 -l8 ubuntu-efi-disk 
      00000552: 0000000000000800                   ........
      
    5. 那么LastUsableLBA是多少呢?
      
      nick@nick-sager:~/workspace/debootstrap$ xxd -u -e -d -g8 -s 560 -l8 ubuntu-efi-disk 
      00000560: 00000000009C3FDE                   .?......
      
      这个计算的逻辑是什么呢?我的磁盘文件大小是5242880000bytes换算成LBA的数量就是5242880000/512=10240000=0x9C4000,那么最后的backup GPT header大小就是0x9C4000-0x9C3FDE=0x22=34,所以,这个34是一个最优解,而且是足够的,而我在使用fdisk时候和普通人一样犯了懒惰的毛病使用默认值2048,这个也许对于最大可能性的GPT partition entry是必须的,但是对于普通的磁盘分区实在是太奢侈了!所以,以后我要养成习惯使用这个magic word 34不过好像fdisk压根儿就不让你这么做!2048是默认最小值!马上打脸,尴尬了。所以,应该使用gdisk!!!
    6. 显示DiskGUID有些问题,因为
      
      typedef struct _GUID {
        unsigned long  Data1;
        unsigned short Data2;
        unsigned short Data3;
        unsigned char  Data4[8];
      } GUID;
      
      从gdisk看到的GUID是
      Disk identifier (GUID): 5B513127-16FE-B34D-A5EF-B1996CE64DCD
      所以,这个显示的是byte order。
      
      nick@nick-sager:~/workspace/debootstrap$ xxd -u  -d -g1 -s 568 -l16 ubuntu-efi-disk 
      00000568: 27 31 51 5B FE 16 4D B3 A5 EF B1 99 6C E6 4D CD  '1Q[..M.....l.M.
      
    7. 分区表在第几个LBA呢?为什么是第2个,这个当然是很明显的,protective MBR后面是GPT header,然后就是PartitionEntryLBA,所以,当然是第2个(从0开始的)。
      
      nick@nick-sager:~/workspace/debootstrap$ xxd -u -e -d -g8 -s 584 -l8 ubuntu-efi-disk 
      00000584: 0000000000000002                   ........
      
    8. NumberOfPartitionEntries分区表有多少个呢?我是没有想到是0x80=128个,也许是因为我还没有设定的默认值。
      
      nick@nick-sager:~/workspace/debootstrap$ xxd -u -e -d -g4 -s 592 -l4 ubuntu-efi-disk 
      00000592: 00000080        
      
    9. SizeOfPartitionEntry应该是8的128,256,512。。。指数倍数增长的。可以看到默认就是0x80=128
      
      nick@nick-sager:~/workspace/debootstrap$ xxd -u -e -d -g4 -s 596 -l4 ubuntu-efi-disk 
      00000596: 00000080    
      
    10. PartitionEntryArrayCRC32目前应该是空的吧?空的也不是0啊!
      
      nick@nick-sager:~/workspace/debootstrap$ xxd -u -e -d -g4 -s 600 -l4 ubuntu-efi-disk 
      00000600: A448F277                             w.H.
      
    你使用gdisk的一个好处是可以节省大约1M的磁盘空间,因为默认第一个可用的LBA在fdisk里是2048,这个有一点点浪费,因为实际上最少34就可以,但是fdisk没有这个功能,gdisk在高级菜单(x)里有一个设置sector alignment(l),如果你设定为128(默认是2048)的话,再创建分区就允许你从默认128最少34开始了。这个是一个高级的功能。看看我修改后的FirstUsableLBA
    
    nick@nick-sager:~/workspace/debootstrap$ xxd -u -e -d -g8 -s 552 -l8 ubuntu-efi-disk 
    00000552: 0000000000000022                   ".......
    
    现在看看我修改后的FirstUsableLBA是0x22=34,非常的紧凑了。
  2. 这个是GPT Partition Entry的结构
    Mnemonic Byte Offset Byte Length Description
    PartitionTypeGUID 0 16 Unique ID that defines the purpose and type of this Partition. A value of zero defines that this partition entry is not being used. 这个不是分区自己的GUID而是类型的GUID,比如EFI system partition类型的GUID就是C12A7328-F81F-11D2-BA4B-00A0C93EC93B (EFI system partition)。这个都是固定的。
    UniquePartitionGUID 16 16 GUID that is unique for every partition entry. Every partition ever created will have a unique GUID. This GUID must be assigned when the GPT Partition Entry is created. The GPT Partition Entry is created whenever the NumberOfPartitionEntrie s in the GPT Header is increased to include a larger range of addresses. 这个是真正的分区自己的GUID
    
    nick@nick-sager:~/workspace/debootstrap$ xxd -u  -d -g16 -s 1040 -l16 ubuntu-efi-disk 
    00001040: D3AC9215B87599478B122695DFCF56E2  .....u.G..&...V.
    
    验证使用gdisk/fdisk:
    
    Partition number (1-2): 1
    Partition GUID code: C12A7328-F81F-11D2-BA4B-00A0C93EC93B (EFI system partition)
    Partition unique GUID: 1592ACD3-75B8-4799-8B12-2695DFCF56E2
    First sector: 128 (at 64.0 KiB)
    Last sector: 1050623 (at 513.0 MiB)
    Partition size: 1050496 sectors (512.9 MiB)
    Attribute flags: 0000000000000000
    Partition name: 'EFI system partition'
    
    StartingLBA 32 8 Starting LBA of the partition defined by this entry.
    
    nick@nick-sager:~/workspace/debootstrap$ xxd -u -e -d -g8 -s 1056 -l8 ubuntu-efi-disk 
    00001056: 0000000000000080                   ........
    
    这个就是First sector: 128 (at 64.0 KiB),0x80=128
    EndingLBA 40 8 Ending LBA of the partition defined by this entry.
    
    nick@nick-sager:~/workspace/debootstrap$ xxd -u -e -d -g8 -s 1064 -l8 ubuntu-efi-disk 
    00001064: 00000000001007FF                   ........
    
    这个就是Last sector: 1050623 (at 513.0 MiB),因为0x1007FF=1050623
    Attributes 48 8 Attribute bits, all bits reserved by UEFI 我重新安装grub之后,让我们看看EFI system partition的性质有没有变化
    
    nick@nick-sager:~/workspace/debootstrap$ xxd -u -e -d -g8 -s 1072 -l8 ubuntu-efi-disk 
    00001072: 0000000000000000                   ........
    
    为什么是空的呢?我查看我的笔记本的EFI表也是如此
    
    nick@nick-sager:~/workspace/debootstrap$ sudo xxd -u -e -d -g8 -s 1072 -l8 /dev/nvme0n1
    00001072: 0000000000000000                   ........
    
  3. 这个是GPT partition entry attribute table
    Bits Name Description
    Bit 0 Required Partition If this bit is set, the partition is required for the platform to function. The owner/creator of the partition indicates that deletion or modification of the contents can result in loss of platform features or failure for the platform to boot or operate. The system cannot function normally if this partition is removed, and it should be considered part of the hardware of the system. Actions such as running diagnostics, system recovery, or even OS install or boot could potentially stop working if this partition is removed. Unless OS software or firmware recognizes this partition, it should never be removed or modified as the UEFI firmware or platform hardware may become non-functional.
    Bit 1 No Block IO Protocol If this bit is set, then firmware must not produce an EFI_BLOCK_IO_PROTOCOL device for this partition. See Section 13.3.2 for more details. By not producing an EFI_BLOCK_IO_PROTOCOL partition, file system mappings will not be created for this partition in UEFI.
    Bit 2 Legacy BIOS Bootable This bit is set aside by this specification to let systems with traditional PC-AT BIOS firmware implementations inform certain limited, special-purpose software running on these systems that a GPT partition may be bootable. For systems with firmware implementations conforming to this specification, the UEFI boot manager (see chapter 3) must ignore this bit when selecting a UEFI-compliant application, e.g., an OS loader (see 2.1.3). Therefore there is no need for this specification to define the exact meaning of this bit.
    Bits 3-47 Undefined and must be zero. Reserved for expansion by future versions of the UEFI specification.
    Bits 48-63 Reserved for GUID specific use. The use of these bits will vary depending on the PartitionTypeGUID. Only the owner of the PartitionTypeGUID is allowed to modify these bits. They must be preserved if Bits 0–47 are modified.
  4. 我刚刚才发现我的旧笔记本之所以必须启动时候设定legacyboot(CSM)的原因是我当初安装的时候磁盘分区采用的是MBR/DOS而不是GPT,所以,压根就没有efi分区。
  5. 我发现了一些端倪,在/boot/efi/BOOT/grub.cfg里
    
    nick@nick-sager:~/workspace/debootstrap$ sudo cat /boot/efi/EFI/ubuntu/grub.cfg
    search.fs_uuid 92d635c6-8ab6-4bfb-8d12-2836774e77c5 root 
    set prefix=($root)'/boot/grub'
    configfile $prefix/grub.cfg
    
    这里的这个UUID是什么?我一开始以为是disk-uuid或者是partition-uuid,都不是,原来是filesystem-uuid。
    
    nick@nick-sager:~/workspace/debootstrap$ sudo blkid  /dev/nvme0n1p2
    /dev/nvme0n1p2: UUID="92d635c6-8ab6-4bfb-8d12-2836774e77c5" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="1cdd8b75-0e3f-4f9d-ad6d-785f38484626"
    
    但是这样子依然不成功。UEFI关于EFI system partition的说明:
    The first block (sector) of a partition contains a data structure called the BIOS Parameter Block (BPB) that defines the type and location of FAT file system on the drive. The BPB contains a data structure that defines the size of the media, the size of reserved space, the number of FAT tables, and the location and size of the root directory (not used in FAT32). The first block (sector) also contains code that will be executed as part of the boot process on a legacy system. This code in the first block (sector) usually contains code that can read a file from the root directory into memory and transfer control to it. Since EFI firmware contains a file system driver, EFI firmware can load any file from the file system with out needing to execute any code from the media.
    这里是BPB 这个表是我需要了解的。
    Sector offset BPB offset Field length Description
    0x00B 0x00 25 BYTEs DOS 3.31 BPB
    0x024 0x19 DWORD Logical sectors per FAT
    0x028 0x1D WORD Mirroring flags etc.
    0x02A 0x1F WORD Version
    0x02C 0x21 DWORD Root directory cluster
    0x030 0x25 WORD Location of FS Information Sector
    0x032 0x27 WORD Location of backup sector(s)
    0x034 0x29 12 BYTEs Reserved (Boot file name)
    0x040 0x35 BYTE Physical drive number
    0x041 0x36 BYTE Flags etc.
    0x042 0x37 BYTE Extended boot signature (0x29)
    0x043 0x38 DWORD Volume serial number
    0x047 0x3C 11 BYTEs Volume label
    0x052 0x47 8 BYTEs File-system type
    Format of standard DOS 2.0 BPB for FAT12 (13 bytes):
    Sector offset BPB offset Field length Description
    0x00B 0x00 WORD Bytes per logical sector
    0x00D 0x02 BYTE Logical sectors per cluster
    0x00E 0x03 WORD Reserved logical sectors
    0x010 0x05 BYTE Number of FATs
    0x011 0x06 WORD Root directory entries
    0x013 0x08 WORD Total logical sectors
    0x015 0x0A BYTE Media descriptor
    0x016 0x0B WORD Logical sectors per FAT
    Format of standard DOS 3.31 BPB for FAT12, FAT16 and FAT16B (25 bytes)。
    Sector offset BPB offset Field length Description
    0x00B 0x00 13 BYTEs DOS 2.0 BPB
    0x018 0x0D WORD Physical sectors per track (identical to DOS 3.0 BPB)
    0x01A 0x0F WORD Number of heads (identical to DOS 3.0 BPB)
    0x01C 0x11 DWORD Hidden sectors (incompatible with DOS 3.0 BPB)
    0x020 0x15 DWORD Large total logical sectors
    我发现了我第一个愚蠢的地方,我居然使用vfat来创建fat32文件!这个简直是白痴!!!但是改正这个错误并没有让我成功,于是我才意识到我可能需要qemu的支持:这里明确的说了我必须使用bios文件。这里是源头文章 我最大的一个错误认识就是以为UEFI本身有能力从媒介探索bootloader,错了,它必须依靠BIOS的功能,我之前和BIOS打了那么多交道居然没有意识到这个概念! 远比我想象的复杂,因为如何建立EFI-var这个就是一个大的问题。我当然不想搞乱我自己的系统吧!休息一下啊。

四月十六日 等待变化等待机会

  1. 每种partition type也是一个GUID,我保存一个拷贝
  2. 所以,按照这个我可以初步的用UEFI boot。具体是这样子的。
    1. 使用arch-chroot进入虚拟机在安装grub-install之前把UEFI system partition,比如(/dev/loopXp1,这里的X是具体loop mount的设备)mount到/boot/efi,这样子安装命令就是最简单的:grub-install /dev/loopX,因为默认的target就是x86_64-efi,而默认的efi-directory也是/boot/efi 我发现所谓的device.map是不需要的,因为你启动的时候已经把硬盘文件作为参数传递给qemu了,唯一不知道的是哪一个是内核存在的文件系统的uuid
    2. 安装的结果是什么呢?在efi目录下是针对ubuntu创建了一个所谓的grub.cfg。它设定了grub启动传递给内核的参数就是文件系统的uuid,注意这个不是UEFI而是你的linux系统所在的文件系统。
    3. 如何启动呢?首先安装ovmf,它里面有很多的bios文件,我根据指引使用最简单的这个OVMF_CODE_4M.fd,需要本地一个拷贝因为使用raw接口参数需要权限:
      
      qemu-system-x86_64 -drive if=pflash,format=raw,file=./OVMF_CODE_4M.fd -hda ubuntu-efi-disk -m 4G
      
      这样子就可以看到我们grub-install创建的grub启动菜单了。而且有一个额外的UEFI-var的编辑菜单,这个似乎是可以存储在UEFI system partition的这个似乎要配合使用另一个OVMF-Var的bios文件才可以吧?,只不过在进入内核启动的时候应该是驱动和console的参数设置的问题会花屏,不过登陆界面是正常的。
    总而言之,我终于可以qemu-UEFI-boot,并且全套制作磁盘文件的流程都走通了!!!
  3. 花屏似乎在我使用UEFI设置菜单里选择解析度为800x640以后就解决了。

四月十七日 等待变化等待机会

  1. 应该说模拟一个虚拟机是相当的复杂的,目前我初步解决了文件系统和启动部分,接下来一个很大的领域就是网络。这是一个巨大的课题,有很多要补课的。感觉这个arch-wiki不是太准确与系统,虽然是很好也许我没有完全理解,还是先从基本的qemu的文档看起来。这里是另一个大的文档。 我现在还是没有头绪,比如我在参数里创建了设备那么怎么设置应该是操作系统的事情和qemu没有关系了吧?
    
    qemu-system-x86_64 -drive if=pflash,format=raw,file=./OVMF_CODE_4M.fd -drive if=pflash,format=raw,file=OVMF_VARS_4M.fd -hda ubuntu-efi-disk -m 4G -netdev user,id=mynet0,net=192.168.76.0/24,dhcpstart=192.168.76.9 -net nic,macaddr=52:54:00:12:34:56
    
    现在可以看到设备,但是dhcp并没有自己运行?
    
    root@nick-sager:/boot/grub# cat /etc/systemd/network/ethernet.network 
    [Match]
    Name=enp0s3
    
    [Network]
    DHCP=yes
    
    难道是要开机启动服务?

四月十九日 等待变化等待机会

  1. 昨天花了快一天时间保税,顺便把旧的笔记本电脑启动的问题解决一下,应该是多种原因,归根结底可能是网络和显示,前者是各种开机访问的网络被防火墙屏蔽了,比如packagekit.service以及各种在线账户开机即链接等等。后者比较复杂可能是nvidia显卡驱动动态编译造成的?以后再说吧?
  2. 现在需要从头学习网络的基本问题:
    1. There are two parts to networking within QEMU:

      • the virtual network device that is provided to the guest (e.g. a PCI network card).
      • the network backend that interacts with the emulated NIC (e.g. puts packets onto the host's network).

      There are a range of options for each part. By default QEMU will create a SLiRP user network backend and an appropriate virtual network device for the guest (eg an E1000 PCI card for most x86 PC guests), as if you had typed -net nic -net user on your command line.

      这个真的是提纲契领的精辟啊!两个问题一个是虚拟硬件,一个是怎么提供数据包!
    2. Note - if you specify any networking options on the command line (via -net or -netdev) then QEMU will require you to provide options sufficient to define and connect up both parts.
      这一点也是非常的关键,就是说两者缺一不可,而且一定要一一对应起来,如同两条腿走路一样必须都提供才行。
    3. Note - if you are using the (default) SLiRP user networking, then ping (ICMP) will not work, though TCP and UDP will. Don't try to use ping to test your QEMU network configuration!
      这一点应该是大多数初学者都会犯的错误,就是不能期待用ping来测试。
    4. 提供了两个更加详细的资料供详细阅读:
      • QEMU Networking on wikibooks.org, mainly dealing with Linux hosts
      • QEMU Networking on bsdwiki, showing used networking principles and dealing with BSD hosts
      我首先快速浏览发现这个图非常的说明问题,真是一图顶千言啊!
      1 User Mode Networking – In this mode, the QEMU virtual machine automatically starts up an internal DHCP server on an internal networkaddress -10.0.2.2/24. This is internal to the guest environment and is not visible from the host environment. If the guest OS is set up for DHCP, the guest will get an IP address from this internal DHCP server. The QEMU virtual machine will also gateway packets onto the host network through 127.0.0.1. In this way, QEMU can provide an automatic network environment for the QEMU user without any manual configuration.
      所以,一个最最简单的user模式包含了多少的细节啊,每一句每一个字都值得我反复理解!
    5. 现在回过头来看我的虚拟机究竟要怎么设置最最基本的呢?一个小问题是我的locale设置是这样子的
      
        C.UTF-8... done
        en_US.UTF-8... done
        zh_CN.UTF-8... done
      
      我如果在qemu-system-x86_64不加任何的network的参数的确是创建了最最基本的网络,但是我的ssh服务没有起来,我猜想是我在debootstrap里安装了文件系统的包,但是没有激活服务吧?systemctl enable ssh。总之我无法从Host去ssh到虚拟机,我一开始验证我能否在虚拟机里使用ssh登陆,但是这个是特殊的root用户,ssh大概有默认的PermitRootLogin设置为no吧?虽然尽管我在/etc/ssh/sshd_config里没有看到它是no,但是这个也许是pam之类的安全问题,只能创建其他用户显示基本的openssh-server的功能是work的,那么从host不能login就纯粹还是网络的问题。
    6. 我是直接使用类似于原始的磁盘文件,而不是qemu或者kvm之类的其他虚拟机的特定格式,这个肯定是笨拙的,所以才会有这样子的警告
      
      WARNING: Image format was not specified for 'ubuntu-efi-disk' and probing guessed raw.
               Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
               Specify the 'raw' format explicitly to remove the restrictions.
      
      这个应该是我的文件系统为只读的原因吧?我对于怎样表达我的磁盘是raw有些疑惑,本来是很简单的问题,但是似乎是有冲突,直到看到这个帖子似乎他的问题和我的比较的相似,我决定采用这个更加简单的参数
      
      qemu-system-x86_64 -bios /usr/share/ovmf/OVMF.fd -drive format=raw,file=ubuntu-efi-disk -m 4G 
      
      不再有警告了,而且可以正常的发现UEFI的loader和我的ubuntu的菜单。与此相对应的是我之前采用的./OVMF_CODE_4M.fd被qemu说是qemu: could not load PC BIOS './OVMF_CODE_4M.fd'。这个是怎么回事? 尽管没有了警告但是我的文件系统依然是read-only!难道是我的grub菜单上写的吗?我猜想是不是因为我现在还是loopmount这个磁盘文件呢?这个猜测显然是无知的! 难道真的是我想的那样子是grub的设置吗?
      
              search --no-floppy --fs-uuid --set=root 98a1016c-7d13-4b2b-8db9-98e9ec541a69
              linux   /boot/vmlinuz-5.15.0-25-generic root=UUID=98a1016c-7d13-4b2b-8db9-98e9ec541a69 ro quiet splash $vt_handoff
              initrd  /boot/initrd.img-5.15.0-25-generic
      
      我自己都有些佩服自己了,正常的Linux启动对于内核所在的文件分区往往是要保护一下吧?所以就设定了ro,那么我现在这么做是否违反了这个原则呢?正常的linux系统是在什么时间点设定文件系统是可写的呢?总之,我这么做的确解决了问题,login的速度明显加快了,原本应该就是read-only的文件系统写操作失败耽误了返回。解决了磁盘只读的问题,先休息一下吧。其实我并没有解决,实际上我的虚拟机并没有直接写文件到磁盘文件,难道是cache,关机看看。
    7. 这里有很多的qemu的测试磁盘这个是debian的一些预编译的镜像吧?这个Debian Quick Image Baker是什么鬼?也许我之前做的一些实验就是qemu-debootstrap的一些工作吧?看到评论有提到mmdebstrap,不过这个应该还是debian的,并不是针对ubuntu的吧?更不要说有人提到debos,这些工具真的是五花八门。debos似乎更加的灵活?
    8. 看来我这么干是违背常识的文件镜像被损坏了!怎么办呢?我决定修复文件系统:
      
      sudo losetup --show -Pf ubuntu-efi-disk
      dev=$(losetup -l | grep ubuntu-efi-disk | cut -d' ' -f1)
      sudo mkfs.ext4 ${dev}p2
      
      果然看到我之前在两个方向同时写文件系统造成的问题,比如
      
      nick@nick-sager:~/workspace/debootstrap$ sudo fsck.ext4 /dev/loop35p2
      e2fsck 1.46.5 (30-Dec-2021)
      /dev/loop35p2 contains a file system with errors, check forced.
      Pass 1: Checking inodes, blocks, and sizes
      Inode 54028, i_blocks is 16, should be 8.  Fix? yes
      Pass 2: Checking directory structure
      Entry '.viminfo' in /root (33) has deleted/unused inode 59371.  Clear? yes
      Pass 3: Checking directory connectivity
      Unconnected directory inode 130221 (/home/nick/???)
      Connect to /lost+found? yes
      Pass 4: Checking reference counts
      Inode 33 ref count is 3, should be 5.  Fix? yes
      Inode 59370 ref count is 1, should be 2.  Fix? yes
      Inode 130221 ref count is 3, should be 2.  Fix? yes
      Pass 5: Checking group summary information
      Block bitmap differences:  -(33331--33334) -33474 -(532628--532632) -(574128--574138) -984580 +(1041007--1041009) +1047559
      Fix? yes
      Free blocks count wrong for group #0 (17197, counted=15150).
      Fix? yes
      Free blocks count wrong for group #1 (6606, counted=6588).
      Fix? yes
      Free blocks count wrong for group #2 (32768, counted=30721).
      Fix? yes
      Free blocks count wrong for group #16 (24429, counted=24420).
      Fix? yes
      Free blocks count wrong for group #17 (4981, counted=4974).
      Fix? yes
      Free blocks count wrong for group #30 (26970, counted=26945).
      Fix? yes
      Free blocks count wrong for group #31 (7162, counted=7163).
      Fix? yes
      Free blocks count wrong (524863, counted=590859).
      Fix? yes
      Inode bitmap differences:  -59371 -(59377--59378) -129853 -130031 -130055 -(130130--130131) -130186
      Fix? yes
      Free inodes count wrong for group #16 (5470, counted=5443).
      Fix? yes
      Directories count wrong for group #16 (210, counted=219).
      Fix? yes
      Free inodes count wrong (215559, counted=225499).
      Fix? yes
      
      /dev/loop35p2: ***** FILE SYSTEM WAS MODIFIED *****
      /dev/loop35p2: 61925/287424 files (0.2% non-contiguous), 557808/1148667 blocks
      
    9. 但是/var依旧是一个镜像,因为文件并没有写到磁盘,这个说明了我对于boot过程还是不清楚,就比如一般的介绍都是浮于表面,语焉不详。吃饭以后再说吧。
    10. 其实是一个很简单的问题,我始终理解反了,我一直以为是我的host可以自由访问guest,实际上是相反的,因为默认的设置是这样子的:
      The guest OS will see an E1000 NIC with a virtual DHCP server on 10.0.2.2 and will be allocated an address starting from 10.0.2.15. A virtual DNS server will be accessible on 10.0.2.3, and a virtual SAMBA file server (if present) will be accessible on 10.0.2.4 allowing you to access files on the host via SAMBA file shares.
      我其实早就看到这个图,但是始终没有理解。你从host是不能简单的ping这些ip,但是在虚拟机上是可以自由访问所有的ip的,因为DNS在10.0.2.3是做了解析的,这个怎么做到的,我不知道,肯定不是简单的在host操作系统层级,应该是qemu-system做了某种映射吧?总而言之,从guest是可以访问外界的。比如你可以直接在虚拟机里ping www.baidu.com,这不就够了吗?
    11. 我遭遇了第一次的沉重打击,就是说我在所谓的虚拟机里的命令并不仅仅限于虚拟机,而是整个我的host machine!因为我在虚拟机里的关机居然直接把我的笔记本给shutdown了。这个怎么可能呢?一定是我不小心使用ssh登陆到了host才造成的!这个真的是非常的危险!
  3. 我原来不知道这个-boot的参数的意义:
    parameter description
    a,b stand for the floppy drives 1 and 2
    c stands for the first hard disk
    d stands for the first CD-ROM drive
    n stand for Ether-boot network adapters

    For example, qemu-system-ARCH [...] -boot order=ndc first tries to boot from network, then from the first CD-ROM drive, and finally from the first hard disk.

    所以,这个更像是boot-order参数。
  4. 关于设备的加载我必须非常的小心,比如说我的笔记本重启之后我注意到两块nvme的设备顺序就变了,我原来的操作系统是/dev/nvme0n1,现在就变成了/dev/nvme1n1,这个是非常的正常,很多时候硬盘也不一定每次都是hda,总之只有UUID是唯一的。
  5. 找了一上午可能需要就是这个host port forwarding
    
    qemu-system-x86_64 -bios /usr/share/ovmf/OVMF.fd -drive format=raw,file=ubuntu-efi-disk -m 4G -netdev user,id=network0,hostfwd=tcp::5555-:22 -device e1000,netdev=network0,mac=52:54:00:12:34:56
    
    因为这样子我们把guest的ssh默认port 22 forward到了host的5555,于是我们可以ssh localhost -p 5555来登陆guest!这个就是我需要的,可是我却一直没有摸到门路! 这个工作模式似乎我可以满足了!我真的需要创建TAP吗?也许是下一步有进一步的需求吧?因为这个学习曲线是很陡峭的。
  6. 重新阅读我惊奇的发现linux-efi-stub,这个是一个很神奇的feature:
    EFI stub feature in Linux means that the kernel image looks like an EFI application, so the kernel can be directly loaded without a separate bootloader - skipping GRUB (the most popular bootloader for Linux).
    这个我记得之前只能是在BIOS里的EFI菜单里才能做到,那么也就是说linux kernel遵循了EFI的spec实现了EFI的那些回调函数,然后存储了启动参数?但是这些本来是在ESP的efi的binary才。。。?我还是不理解。我的理解是BIOS厂商遵循EFI规范允许你存储这些参数在NVRAM里,也就是意味着kernel要能够写这些参数,当然这个是在EFI的接口对应下。。。
  7. 重点还是阅读我能够容易实验的部分吧:qemu和efi的部分。我其实能够感受到作者的疑惑,因为之前我使用IPMI以及UEFI的一些经验告诉我bios里是有些值很让人摸不着头脑,大概就是这个boot option以及boot order能把人抓狂,因为配合一个所谓的next boot value有非常多的组合,尤其是在系统之前boot failure会自动更改,这一点类似于我在grub菜单里的所谓的recovery原理吧?总之,我怀疑是这些把作者搞糊涂了,尤其是怎么进入grub菜单的,这个是很有趣很烧脑的机制。在EFI/BOOT里的efi文件是让你进到EFI/ubuntu下的efi,两者有区别吗?我做了一个小实验来验证我的想法:
    1. 我首先要找到我的ESP,经过文件系统corruption的教训我不再敢于在host里直接mount我的磁盘镜像,读写都要在虚拟机里进行。
    2. 首先看看我的虚拟机的磁盘是怎么样的,我只能看到我只有一个/dev/sda设备,尽管我目前的分区设备是/dev/sda2
      
      $ sudo gdisk -l /dev/sda
      Partition table scan:
        MBR: protective
        BSD: not present
        APM: not present
        GPT: present
      
      Found valid GPT with protective MBR; using GPT.
      Disk /dev/sda: 10240000 sectors, 4.9 GiB
      Model: QEMU HARDDISK   
      Sector size (logical/physical): 512/512 bytes
      Disk identifier (GUID): 5B513127-16FE-B34D-A5EF-B1996CE64DCD
      Partition table holds up to 128 entries
      Main partition table begins at sector 2 and ends at sector 33
      First usable sector is 34, last usable sector is 10239966
      Partitions will be aligned on 128-sector boundaries
      Total free space is 94 sectors (47.0 KiB)
      
      Number  Start (sector)    End (sector)  Size       Code  Name
         1             128         1050623   512.9 MiB   EF00  EFI system partition
         2         1050624        10239966   4.4 GiB     8300  Linux
      
      所以,我要找的ESP在/dev/sda1上。
    3. 那么先把它mount吧:
      
      sudo mount /dev/sda1 /boot/efi
      
      这里为什么ESP没有正常的被mount在/boot/efi呢?我的笔记本就是这么做的,看来有些其他的配置需要让bootloader或者内核知道吧?
    4. 我究竟想看到什么呢?我在找/boot/efi/NvVars,因为我为了验证qemu的默认的EFI BIOS文件有能力配置EFI VAR的思路特意把ESP下的这个/NvVars删除来确保我在grub启动菜单里的EFI配置是保留在这个文件里的,这个是可以理解的,因为qemu不大可能去直接和NVRAM交互改写系统的EFI var,这个简直就是灾难,qemu也没有这个权限与能力吧。所以,就在ESP里写下,这个到底是不是Linux EFI stub呢?还是说这个是grub制作的呢?因为它是在grub菜单最后加上的,我是没有在grub.cfg里看到这个,这个似乎是动态加入的?确认一下吧!这个应该是grub自己加入的!看看这个 /etc/grub.d/30_uefi-firmware就知道了,这里定义的是什么呢?:
      
      EFI_VARS_DIR=/sys/firmware/efi/efivars
      EFI_GLOBAL_VARIABLE=8be4df61-93ca-11d2-aa0d-00e098032b8c
      OS_INDICATIONS="$EFI_VARS_DIR/OsIndicationsSupported-$EFI_GLOBAL_VARIABLE"
      
      if [ -e "$OS_INDICATIONS" ] && \
         [ "$(( $(printf 0x%x \'"$(cat $OS_INDICATIONS | cut -b5)"\') & 1 ))" = 1 ]; then
        LABEL="UEFI Firmware Settings"
      
      也就是说要看下面这个文件的第五个byte和1的与来决定是否动态添加这个菜单UEFI Firmware Settings。那么这个OsIndicationsSupported-xxx到底是谁写的呢?可能是安装包的时候设定的吧?。 这里/sys/firmware/efi/efivars/OsIndicationsSupported-8be4df61-93ca-11d2-aa0d-00e098032b8c是什么呢?让我们看看二进制吧:
      
      nick@nick-sager:/sys/firmware/efi/efivars$ xxd OsIndicationsSupported-8be4df61-93ca-11d2-aa0d-00e098032b8c 
      00000000: 0600 0000 7f00 0000 0000 0000            ............
      
      这个我一时莫不清头脑,但是我坚信它是IPMI里的相关的启动参数吧?
    5. 其他的参数我倒是看明白了一点,比如我自己的笔记本里是这样的boot order:
      
      nick@nick-sager:/sys/firmware/efi/efivars$ xxd -d -s64 -g1 Boot0000-8be4df61-93ca-11d2-aa0d-00e098032b8c
      00000064: 02 02 04 04 34 00 5c 00 45 00 46 00 49 00 5c 00  ....4.\.E.F.I.\.
      00000080: 75 00 62 00 75 00 6e 00 74 00 75 00 5c 00 73 00  u.b.u.n.t.u.\.s.
      00000096: 68 00 69 00 6d 00 78 00 36 00 34 00 2e 00 65 00  h.i.m.x.6.4...e.
      00000112: 66 00 69 00 00 00 7f ff 04 00 52 43              f.i.......RC
      
      这个说明了boot order里第一个是/boot/efi/EFI/ubuntu/shimx64.efi,这个是什么呢?
      
      nick@nick-sager:/sys/firmware/efi/efivars$ xxd -d -g1 Boot2001-8be4df61-93ca-11d2-aa0d-00e098032b8c
      00000000: 07 00 00 00 01 00 00 00 04 00 45 00 46 00 49 00  ..........E.F.I.
      00000016: 20 00 55 00 53 00 42 00 20 00 44 00 65 00 76 00   .U.S.B. .D.e.v.
      00000032: 69 00 63 00 65 00 00 00 7f ff 04 00 52 43        i.c.e.......RC
      
      很明显是USB
      
      nick@nick-sager:/sys/firmware/efi/efivars$ xxd -d -g1 Boot2002-8be4df61-93ca-11d2-aa0d-00e098032b8c 
      00000000: 07 00 00 00 01 00 00 00 04 00 45 00 46 00 49 00  ..........E.F.I.
      00000016: 20 00 44 00 56 00 44 00 2f 00 43 00 44 00 52 00   .D.V.D./.C.D.R.
      00000032: 4f 00 4d 00 00 00 7f ff 04 00 52 43              O.M.......RC
      
      这个是DVD/CDRom
      
      nick@nick-sager:/sys/firmware/efi/efivars$ xxd -d -g1 Boot2003-8be4df61-93ca-11d2-aa0d-00e098032b8c
      00000000: 07 00 00 00 01 00 00 00 04 00 45 00 46 00 49 00  ..........E.F.I.
      00000016: 20 00 4e 00 65 00 74 00 77 00 6f 00 72 00 6b 00   .N.e.t.w.o.r.k.
      00000032: 00 00 7f ff 04 00 52 43                          ......RC
      
      这个当然是network了
      
      nick@nick-sager:/sys/firmware/efi/efivars$ xxd -d -g1 BootCurrent-8be4df61-93ca-11d2-aa0d-00e098032b8c 
      00000000: 06 00 00 00 00 00                                ......
      
      current是6?
      
      nick@nick-sager:/sys/firmware/efi/efivars$ xxd -d -g1 BootOrder-8be4df61-93ca-11d2-aa0d-00e098032b8c 
      00000000: 07 00 00 00 00 00 01 20 02 20 03 20              ....... . . 
      
      这个肯定也是IPMI里相关的那些bits。
    6. 当然这里关于shimx64.efi远比我猜想的复杂:

      Typically, EFI/ubuntu/grubx64.efi on the EFI System Partition (ESP) is the GRUB binary, and EFI/ubuntu/shimx64.efi is the binary for shim. The latter is a relatively simple program that provides a way to boot on a computer with Secure Boot active. On such a computer, an unsigned version of GRUB won't launch, and signing GRUB with Microsoft's keys is impossible, so shim bridges the gap and adds its own security tools that parallel those of Secure Boot. In practice, shim registers itself with the firmware and then launches a program called grubx64.efi in the directory from which it was launched, so on a computer without Secure Boot (such as a Mac), launching shimx64.efi is just like launching grubx64.efi. On a computer with Secure Boot active, launching shimx64.efi should result in GRUB starting up, whereas launching grubx64.efi directly probably won't work.

      Note that there's some ambiguity possible. In particular, if you want to use a boot manager or boot loader other than GRUB in a Secure Boot environment with shim, you must call that program grubx64.efi, even though it's not GRUB. Thus, if you were to install rEFInd on a Secure Boot-enabled computer, grubx64.efi could be the rEFInd binary. This binary would probably not reside in EFI/ubuntu, though; both it and a shim binary would probably go in EFI/refind. Also, as you've got a Mac (which doesn't support Secure Boot), there's no need to install rEFInd in this way; it makes much more sense to install rEFInd as EFI/refind/refind_x64.efi (its default location and name).

      Note that the rEFInd documentation includes a whole page on Secure Boot. Chances are you won't benefit from reading it, user190735, since you're using a Mac. I mention it only in case some other reader comes along who's trying to use rEFInd in conjunction with Secure Boot.

      总而言之,是和secure boot有关,这个领域就太复杂了,我连碰都不敢碰! 这里给出了权威的解释,不用瞎猜了。
      
      	This directory exposes interfaces for interactive with
      	EFI variables.  For more information on EFI variables,
      	see 'Variable Services' in the UEFI specification
      	(section 7.2 in specification version 2.3 Errata D).
      
      	In summary, EFI variables are named, and are classified
      	into separate namespaces through the use of a vendor
      	GUID.  They also have an arbitrary binary value
      	associated with them.
      
      我下载的版本是2.8远远高于2.3,已经有了很多改变,不过模拟应该不受影响吧?这个实现也是交给各个BIOS提供商去自己在NVRAM里实现存储吧,只要你保证输出相应的实现接口函数,至于说具体存储就是无关的,所以,Linux也能够模拟这些吧?
  8. 总而言之,通过grub的custom菜单暴露EFI variable配置,这个是通过grub配置菜单得到的,但是这里牵扯到了巨大的内容,比如这个菜单它执行的是什么呢?fwsetup在哪里?它是grub内指的吗?为什么locate找不到?唯一相似的是
    
    nick@nick-sager:/etc/grub.d$ locate fwsetup
    /boot/grub/x86_64-efi/efifwsetup.mod
    /home/nick/Downloads/coreboot/payloads/external/GRUB2/grub2/grub-core/commands/efi/efifwsetup.c
    /usr/lib/grub/x86_64-efi/efifwsetup.mod
    
    我对于这个说法将信将疑:

    fwsetup (or firmware-setup) is an option to tell the computer to boot the manufacturer BIOS after the reboot (or to boot directly to manufacturer BIOS if this option is triggered by GRUB).

    On a computer using systemctl you can trigger this option with the command systemctl reboot --firmware-setup

    的确这个是grub的内部命令

    17.4.29 fwsetup

    Command: fwsetup [--is-supported]

    Reboot into the firmware setup menu. If --is-supported option is specified, instead check whether the firmware supports a setup menu and exit successfully if so.

  9. 今天太多的需要消化了,休息吧。
  10. 我的旧笔记本总是遇到启动死机的问题,应该是amd gpu相关的驱动问题吧,只能在grub里加上nomodeset来禁止一些显示的代码吧?

四月二十日 等待变化等待机会

  1. 昨天用眼过度,今天休息一天。

四月二十二日 等待变化等待机会

  1. 多休息了一天。
  2. Linux内核有一篇著名的文档详细的回答了关于TUN/TAP的很多基本概念:
    1. 什么:

      TUN/TAP provides packet reception and transmission for user space programs. It can be seen as a simple Point-to-Point or Ethernet device, which, instead of receiving packets from physical media, receives them from user space program and instead of sending packets via physical media writes them to the user space program.
      事实上我目前使用的openvpn本质上也是一个TUN设备。
    2. 怎么:

      In order to use the driver a program has to open /dev/net/tun and issue a corresponding ioctl() to register a network device with the kernel. A network device will appear as tunXX or tapXX, depending on the options chosen. When the program closes the file descriptor, the network device and all corresponding routes will disappear.
      到底是tun还是tap的选项是什么呢?下面有详细的解说。核心就是要先有/dev/net/tun这个设备文件,往往需要手动自己创建。
    3. tun or tap?

      Depending on the type of device chosen the userspace program has to read/write IP packets (with tun) or ethernet frames (with tap). Which one is being used depends on the flags given with the ioctl().
      tun是IP packet,而tap是ethernet frame。
    4. 文档在哪里:

      这里是tun/tap的大本营吧?我喜欢它的这个logo: 为了迅速理解,看看这个FAQ是值得的。不过很显然的这是来自同一个作者,大侠没有时间去写冗长的文档,基本上是同样的。因为大侠不会把时间浪费给专栏作家也能看懂的FAQ上,主要精力都在具体的例子里,只有真正的实践者才需要精准的指导,而对于浅尝辄止的随意浏览者是不值得浪费时间的。
    5. 例子:

      也许最好的例子是代表了千言万语的解说!这个设置例子说明了一切。为什么要学习呢?我的模糊认识是这个强大的工具是一个灵活的bridge它可以把不同桥段的主机自由的连接,而这一点在虚拟化里至关重要。所以,我需要掌握。但是很显然的,这个是一个非常古老的项目,也就是非常的成熟的,没有那么多的人在热衷于维护了。也许有其他的选择? 或者从高度抽象的角度来看,其实它是非常简单的想法,你创建一个设备,赋予它普通用户能够访问的权限,对它进行读写,而背后的内核代码可以根据设置压缩加密转发给另一个指定目的的设备,说白了就是一个程序,而在用户眼里似乎就是一个设备。确实也没有多少需要解释的。
    总而言之,还是回到qemu的文档上吧!
  3. 创建TAP/TUN_device设备一定是第一步!
    
       $ sudo mkdir /dev/net
       $ sudo mknod /dev/net/tun c 10 200
       $ sudo /sbin/modprobe tun
    
    tun是一个char设备,major 10,minor 200。它需要内核模块tun。
  4. 这个关键的脚本我还不敢尝试,因为还看不大懂,概念模糊。我需要一些更加系统的解说。不过我的总体感觉是TAP/TUN的途径是避免了routing table的复杂操作,而是通过一个转发程序来掩盖它吧?
  5. 看这个文档来应证一些共同的部分:
    if you want simplicity, use the “User Mode Networking” method and use DHCP in the guest OS. If you want strict control of your IP addressing and routing, use the “TUN/TAP Network Interface” method.
    我的感觉是兼听则明,一个复杂的议题最好是找两三家来从不同角度来互相应证,这个也是情报工作的基本方法。从他的例子的描述来看 using one virtual bridge on the host system. All the virtual machines will be attached to the virtual bridge, and in the same vlan (default vlan 0).,似乎需要把虚拟机和主机配置在一个vlan里然后虚拟机依靠virtual bridge把主机的物理设备转接到虚拟机的虚拟设备上?这里的虚拟设备显然是tun/tap,因为更加的灵活。否则要使用模拟物理设备的虚拟机的模拟网卡有可能要给它配置全套的环境吧?我的理解就是在上面user mode下,实际上虚拟机的虚拟物理设备是在一个模拟的物理环境下工作,虚拟机好像真实的操作系统惯例开机使用dhcpclient自动搜索qemu-dhcp-server配置好的环境,这个过程是否可以称之为tunneling呢?我这方面的知识匮乏,感到力不从心。以前在工作中遇到网络问题都是绕着走,现在吃苦头了。

四月二十三日 等待变化等待机会

  1. 首先从宏观概念上明白这个是一体两面的一面,就是创建Virtual Network Device。它是所谓的backend,就是模拟的物理设备,它不同于tap/tun的思路,就是说这个是追求性能或者专门针对硬件的目的。它使用的是参数-device TYPE,netdev=NAME
  2. 这个所谓的nic option是一种捷径,就是它包含了一体两面:

    In case you don't care about configuring every detail of a NIC, you can also create a NIC together with a host backend by using the -nic parameter. For example, you can replace

    -netdev user,id=n1 -device virtio-net-pci,netdev=n1
    

    with:

    -nic user,model=virtio-net-pci
    

    Use -nic model=help to get a list of the supported NIC models.

    Supported NIC models:
    e1000
    e1000-82544gc
    e1000-82545em
    e1000e
    i82550
    i82551
    i82557a
    i82557b
    i82557c
    i82558a
    i82558b
    i82559a
    i82559b
    i82559c
    i82559er
    i82562
    i82801
    ne2k_pci
    pcnet
    pvrdma
    rtl8139
    tulip
    virtio-net-pci
    virtio-net-pci-non-transitional
    virtio-net-pci-transitional
    vmxnet3
    
  3. 偶然注意到boot log里有Unmounting /boot/efi...这里似乎解释的其他?
    
    systemctl daemon-reload
    
    并不能解决问题,因为我的/etc/fstab里是# UNCONFIGURED FSTAB FOR BASE SYSTEM这里的一些回答让我大概明白这个是要自己根据当前的磁盘设备写上去的。
  4. 这里的大侠的启动参数是一个经典的长,可以参考学习。
  5. 启动的时候花屏实际上是两个问题,第一,我可以强硬的在/etc/default/grub里设置显示模式为640x480来解决显卡设置不当的问题,这个基本上可以解决。不过因为默认的grub参数是把启动的文件系统设置为ro,这个grub-mkconfig -o /boot/grub/grub.cfg和直接update-grub似乎差别不是很多吧? 这里有很多的关于initramfs打log的方式,很长,似乎要重新编译? 这里编辑grub参数值得学习,主要是设置console参数

    setup serial/console access

    edit /etc/default/grub:

    1. Set GRUB_CMDLINE_LINUX="" to:

      GRUB_CMDLINE_LINUX="console=tty0 console=ttyS0,115200n8"
      
    2. Uncomment GRUB_TERMINAL=console

    3. Beneath, add the line:

      GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1"
      

    Make the grub config - This MUST be done in a non-systemd-nspawn shell (that means chroot)

    grub-mkconfig -o /boot/grub/grub.cfg
    
  6. 我现在回过头来看我自己的笔记本的/etc/fstab很明显的这个是要自己制作的
    
    # / was on /dev/nvme0n1p2 during installation
    UUID=92d635c6-8ab6-4bfb-8d12-2836774e77c5 /               ext4    rw,errors=remount-ro 0       1
    # /boot/efi was on /dev/nvme0n1p1 during installation
    UUID=82C1-F9D0  /boot/efi       vfat    umask=0077      0       1
    
    那么我现在自己手动设置这个在虚拟机里吧?特别注意这里一定要设置为rw,errors=remount-ro,如果没有rw就不会自己设为文件系统可写。
  7. 总结一下,就是你创建好系统不等于文件系统自己就可以配置好,意思就是说linux是一个非常灵活的,你可以有多种不同的配置,必须要设置/etc/fstab明确文件系统要怎么启动,而在grub菜单上kernel的分区设置为只读是正常的操作,想想看,这是启动的一个步骤而已,更何况还需要initramfs要探索你的驱动硬件等等,这中间出错机会很多的,完全没有必要设定为可写,那样太危险了。所以,正确的做法是在/etc/fstab里设定。而花屏的问题大可以通过禁止修改高解析度的做法,也许设定console也是一个好主意,因为这个几乎是无条件工作的。就是说显卡没有也是可以工作的。

四月二十四日 等待变化等待机会

  1. 一个古老的新问题是我想看看早期启动的log,这个很难吗?我找了一会儿发现Linux kernel的启动参数里有这个earlyprintk,我尝试使用vga/console,ttyS0等等,甚至于按照指示对于serial console使用它的地址/proc/tty/driver/serial里获得。但是都不成功。然后我看见很多大侠直接命令行指定内核以及initrd来启动,这个是可以完全控制的。但是仅仅boot到initramfs是无聊的,我并不知道我要干什么,仅仅是好奇,那么还是做一个正式的boot到ubuntu吧,于是我遇到了一个问题,如果是我自己使用内核的话,系统是不明白root文件系统在哪里的,因为省略了bootloader发现的过程,于是我像当然的模仿grub给文件系统的uuid作为append的参数来指定文件系统,于是一个微妙的故事来了,文件系统的uuid不行,需要partition的uuid。这个是多么的伟大啊,因为我是上个星期才开始有这个概念的,每个文件系统的uuid是藏在开头扇区的某个结构中,可是linux要对付那么多种文件系统,它能够可能一个个的来识别获取吗?所以,它只是要写在GPT的partition table里的分区的uuid。所以,我最后的参数是
    
    qemu-system-x86_64 -kernel tmp/vmlinuz-5.15.0-25-generic -initrd tmp/initrd.img-5.15.0-25-generic  -m 2G -bios /usr/share/ovmf/OVMF.fd -drive format=raw,file=ubuntu-efi-disk -append "root=PARTUUID=8613E0D8-6556-7A47-922D-EDA26D53D20B"
    
    内核和initrd我只能拷贝一份改权限有读否则默认只能root来读太危险,而partition uuid可以使用这个脚本版的gdisk
    
    $ sudo sgdisk -i 2  /dev/loop3
    Partition GUID code: 0FC63DAF-8483-4772-8E79-3D69D8477DE4 (Linux filesystem)
    Partition unique GUID: 8613E0D8-6556-7A47-922D-EDA26D53D20B
    First sector: 1050624 (at 513.0 MiB)
    Last sector: 10239966 (at 4.9 GiB)
    Partition size: 9189343 sectors (4.4 GiB)
    Attribute flags: 0000000000000000
    Partition name: 'Linux'
    
    生活瞬间变得很美好了。
  2. 有时候人就是贪心,我发现在qemu的窗口里看boot log非常的困难,这个是一个同理心,所以,这位大侠把stdio作为console的backend非常的棒,我是蒙了一下才清醒,原来这个设置console的backend是要在-append给linux kernel的
    
    qemu-system-x86_64 -kernel tmp/vmlinuz-5.15.0-25-generic -initrd tmp/initrd.img-5.15.0-25-generic -serial stdio -m 2G  -drive format=raw,file=ubuntu-efi-disk -append "root=PARTUUID=8613E0D8-6556-7A47-922D-EDA26D53D20B console=ttyAMA0 console=ttyS0"
    
    很显然的,我现在根本不需要EFI来帮助启动了,这么着我看到的是早期阶段吗?屏幕上输出这样子
    
    [    0.000000] Command line: root=PARTUUID=8613E0D8-6556-7A47-922D-EDA26D53D20B console=ttyAMA0 console=ttyS0
    
    这个是我传递给内核的参数,然后我发现console=ttyAMA0这个是不需要的,我根本没有这个设备,这里的解释很好!
    • ttyS0 is the device for the first UART serial port on x86 and x86_64 architectures. If you have a PC motherboard with serial ports you'd be using a ttySn to attach a modem or a serial console.
    • ttyUSB0 is the device for the first USB serial convertor. If you have an USB serial cable you'd be using a ttyUSBn to connect to the serial port of a router.
    • ttyAMA0 is the device for the first serial port on ARM architecture. If you have an ARM-based TV box with a serial console and running Android or OpenELEC, you'd be using a ttyAMAn to attach a console to it.
    这位大侠给出了图文并茂的解释,对于没有多少嵌入式开发经验的人很有帮助。我虽然也用过一会儿ttyUSB0,但是对于真实的serial port却感觉意外。笔记本是没有这个port,那么操作系统还是创建了它的驱动,那么如果我指定stdio作为它的backend,它就输出到了我的命令行console,是这个道理吗?当然qemu本身就是虚拟机,本身的标准PC就是包含这个硬件的。 其实我真的理解了吗?不理解,因为我尝试着把传递给内核的参数换回成-append root=PARTUUID=8613E0D8-6556-7A47-922D-EDA26D53D20B console=tty0"或者是console=stdio,结果输出又回到了qemu的窗口。这个说明了什么?我尝试着解释就是说必须要有额外的硬件比如usb设备并且为其专门创建了对应的驱动并且才能把console的输出redirect到这个设备,否则就只能在qemu的窗口里了? 当我再次精简命令干脆去掉initrd,我看到的输出有不同吗?我感觉没有。我原本的信念是在initrd作为早期临时的一个操作系统把硬件检测的工作做完,那么这个过程实在是太快了,我根本没有看到???
  3. 重新学习initrd的目的

    initrd provides the capability to load a RAM disk by the boot loader. This RAM disk can then be mounted as the root file system and programs can be run from it. Afterwards, a new root file system can be mounted from a different device. The previous root (from initrd) is then moved to a directory and can be subsequently unmounted.

    initrd is mainly designed to allow system startup to occur in two phases, where the kernel comes up with a minimum set of compiled-in drivers, and where additional modules are loaded from initrd.

    这是正常的boot流程,我即便读过很多次也并不代表真正理解:
    1. the boot loader loads the kernel and the initial RAM disk
    2. the kernel converts initrd into a “normal” RAM disk and frees the memory used by initrd
    3. if the root device is not /dev/ram0, the old (deprecated) change_root procedure is followed. see the “Obsolete root change mechanism” section below.
    4. root device is mounted. if it is /dev/ram0, the initrd image is then mounted as root
    5. /sbin/init is executed (this can be any valid executable, including shell scripts; it is run with uid 0 and can do basically everything init can do).
    6. init mounts the “real” root file system
    7. init places the root file system at the root directory using the pivot_root system call
    8. init execs the /sbin/init on the new root filesystem, performing the usual boot sequence
    9. the initrd file system is removed
    这里是大多数人引用的如何创建Initrd
    
    find . | cpio --quiet -H newc -o | gzip -9 -n > /boot/imagefile.img
    
  4. 我尝试把initrd解开来看看,结果我印象中很轻易的cpio的操作居然不行!因为它显示的是
    
    $ file initrd.img-5.15.0-25-generic 
    initrd.img-5.15.0-25-generic: ASCII cpio archive (SVR4 with no CRC)
    
    而我简单的使用cpio只有一部分就是一个文件!找了好久,因为我不相信是压缩的问题,才找到这个提示:使用其他工具比如lsinitramfs可以看到文件系统,可是直到我看了这个才意识到其中大有玄机,就是说你需要使用dd去skip才能看到所有的文件。这难道是一种安全机制吗?
    1. 
      $ dd if=../initrd.img-5.15.0-25-generic skip=0| file -
      /dev/stdin: ASCII cpio archive (SVR4 with no CRC)
      
    2. 
      $ dd if=../initrd.img-5.15.0-25-generic skip=0| cpio -it
      .
      kernel
      kernel/x86
      kernel/x86/microcode
      kernel/x86/microcode/AuthenticAMD.bin
      62 blocks
      
    3. 
      $ dd if=../initrd.img-5.15.0-25-generic skip=62| file -
      /dev/stdin: ASCII cpio archive (SVR4 with no CRC)
      
    4. 
      $ dd if=../initrd.img-5.15.0-25-generic skip=62| cpio -it
      kernel
      kernel/x86
      kernel/x86/microcode
      kernel/x86/microcode/.enuineIntel.align.0123456789abc
      kernel/x86/microcode/GenuineIntel.bin
      9004 blocks
      
    5. 
      $ dd if=../initrd.img-5.15.0-25-generic skip=9066|file -
      /dev/stdin: Zstandard compressed data (v0.8+), Dictionary ID: None
      
    6. 
      $ dd if=../initrd.img-5.15.0-25-generic skip=9066|unzstd | file -
      /dev/stdin: ASCII cpio archive (SVR4 with no CRC)
      
    7. 然后dd if=../initrd.img-5.15.0-25-generic skip=9066|unzstd | cpio -it这里的文件太多了
      
      $ dd if=../initrd.img-5.15.0-25-generic skip=9066|unzstd | cpio -it 
      .
      bin
      conf
      conf/arch.conf
      conf/conf.d
      conf/initramfs.conf
      etc
      etc/console-setup
      etc/console-setup/Uni2-Fixed16.psf.gz
      etc/console-setup/cached_UTF-8_del.kmap.gz
      etc/default
      etc/default/console-setup
      etc/default/keyboard
      etc/dhcp
      etc/dhcp/dhclient-enter-hooks.d
      etc/dhcp/dhclient-enter-hooks.d/config
      etc/dhcp/dhclient.conf
      etc/fstab
      etc/ld.so.cache
      etc/ld.so.conf
      etc/ld.so.conf.d
      etc/ld.so.conf.d/libc.conf
      etc/ld.so.conf.d/x86_64-linux-gnu.conf
      etc/modprobe.d
      etc/modprobe.d/amd64-microcode-blacklist.conf
      etc/modprobe.d/blacklist-ath_pci.conf
      etc/modprobe.d/blacklist-firewire.conf
      etc/modprobe.d/blacklist-framebuffer.conf
      etc/modprobe.d/blacklist-rare-network.conf
      etc/modprobe.d/blacklist.conf
      etc/modprobe.d/intel-microcode-blacklist.conf
      etc/modprobe.d/iwlwifi.conf
      etc/mtab
      etc/nsswitch.conf
      etc/udev
      etc/udev/udev.conf
      init
      lib
      lib32
      lib64
      libx32
      run
      sbin
      scripts
      scripts/functions
      scripts/init-bottom
      scripts/init-bottom/ORDER
      scripts/init-bottom/udev
      scripts/init-top
      scripts/init-top/ORDER
      scripts/init-top/all_generic_ide
      scripts/init-top/blacklist
      scripts/init-top/udev
      scripts/local
      scripts/local-premount
      scripts/local-premount/ORDER
      scripts/local-premount/fixrtc
      scripts/local-premount/resume
      scripts/nfs
      scripts/panic
      scripts/panic/ORDER
      scripts/panic/console_setup
      usr
      usr/bin
      usr/bin/cpio
      usr/bin/dd
      usr/bin/dmesg
      usr/bin/fstype
      usr/bin/halt
      usr/bin/ipconfig
      usr/bin/kbd_mode
      usr/bin/kmod
      usr/bin/loadkeys
      usr/bin/losetup
      usr/bin/minips
      usr/bin/nfsmount
      usr/bin/pivot_root
      usr/bin/poweroff
      usr/bin/resume
      usr/bin/run-parts
      usr/bin/setfont
      usr/bin/udevadm
      usr/bin/which
      usr/bin/wget
      usr/bin/wc
      usr/bin/uniq
      usr/bin/uname
      usr/bin/umount
      usr/bin/tty
      usr/bin/true
      usr/bin/tr
      usr/bin/touch
      usr/bin/test
      usr/bin/tee
      usr/bin/tail
      usr/bin/sync
      usr/bin/switch_root
      usr/bin/stty
      usr/bin/static-sh
      usr/bin/stat
      usr/bin/sort
      usr/bin/sleep
      usr/bin/sh
      usr/bin/setkeycodes
      usr/bin/seq
      usr/bin/sed
      usr/bin/run-init
      usr/bin/rmdir
      usr/bin/rm
      usr/bin/reset
      usr/bin/reboot
      usr/bin/readlink
      usr/bin/pwd
      usr/bin/ps
      usr/bin/printf
      usr/bin/pidof
      usr/bin/openvt
      usr/bin/nuke
      usr/bin/mv
      usr/bin/mount
      usr/bin/more
      usr/bin/modinfo
      usr/bin/mktemp
      usr/bin/mkswap
      usr/bin/mknod
      usr/bin/mkfifo
      usr/bin/mkdir
      usr/bin/lzop
      usr/bin/ls
      usr/bin/loadkmap
      usr/bin/loadfont
      usr/bin/ln
      usr/bin/kill
      usr/bin/ip
      usr/bin/ifconfig
      usr/bin/hwclock
      usr/bin/hostname
      usr/bin/gzip
      usr/bin/gunzip
      usr/bin/grep
      usr/bin/fstrim
      usr/bin/fold
      usr/bin/find
      usr/bin/fgrep
      usr/bin/fbset
      usr/bin/false
      usr/bin/expr
      usr/bin/env
      usr/bin/egrep
      usr/bin/echo
      usr/bin/dumpkmap
      usr/bin/du
      usr/bin/dirname
      usr/bin/df
      usr/bin/devmem
      usr/bin/deluser
      usr/bin/deallocvt
      usr/bin/date
      usr/bin/cut
      usr/bin/cp
      usr/bin/cmp
      usr/bin/clear
      usr/bin/chvt
      usr/bin/chroot
      usr/bin/chmod
      usr/bin/cat
      usr/bin/busybox
      usr/bin/blockdev
      usr/bin/basename
      usr/bin/awk
      usr/bin/ash
      usr/bin/arch
      usr/bin/acpid
      usr/bin/[[
      usr/bin/[
      usr/bin/yes
      usr/lib
      usr/lib/firmware
      usr/lib/firmware/3com
      usr/lib/firmware/3com/typhoon.bin
      usr/lib/firmware/acenic
      usr/lib/firmware/acenic/tg1.bin
      usr/lib/firmware/acenic/tg2.bin
      usr/lib/firmware/adaptec
      usr/lib/firmware/adaptec/starfire_rx.bin
      usr/lib/firmware/adaptec/starfire_tx.bin
      usr/lib/firmware/advansys
      usr/lib/firmware/advansys/3550.bin
      usr/lib/firmware/advansys/38C0800.bin
      usr/lib/firmware/advansys/38C1600.bin
      usr/lib/firmware/advansys/mcode.bin
      usr/lib/firmware/bnx2
      usr/lib/firmware/bnx2/bnx2-mips-06-6.2.3.fw
      usr/lib/firmware/bnx2/bnx2-mips-09-6.2.1b.fw
      usr/lib/firmware/bnx2/bnx2-rv2p-06-6.0.15.fw
      usr/lib/firmware/bnx2/bnx2-rv2p-09-6.0.17.fw
      usr/lib/firmware/bnx2/bnx2-rv2p-09ax-6.0.17.fw
      usr/lib/firmware/bnx2x
      usr/lib/firmware/bnx2x/bnx2x-e1-7.13.15.0.fw
      usr/lib/firmware/bnx2x/bnx2x-e1-7.13.21.0.fw
      usr/lib/firmware/bnx2x/bnx2x-e1h-7.13.15.0.fw
      usr/lib/firmware/bnx2x/bnx2x-e1h-7.13.21.0.fw
      usr/lib/firmware/bnx2x/bnx2x-e2-7.13.15.0.fw
      usr/lib/firmware/bnx2x/bnx2x-e2-7.13.21.0.fw
      usr/lib/firmware/cbfw-3.2.5.1.bin
      usr/lib/firmware/cis
      usr/lib/firmware/cis/DP83903.cis
      usr/lib/firmware/cis/LA-PCM.cis
      usr/lib/firmware/cis/NE2K.cis
      usr/lib/firmware/cis/PCMLM28.cis
      usr/lib/firmware/cis/PE-200.cis
      usr/lib/firmware/cis/PE520.cis
      usr/lib/firmware/cis/tamarack.cis
      usr/lib/firmware/ct2fw-3.2.5.1.bin
      usr/lib/firmware/ctfw-3.2.5.1.bin
      usr/lib/firmware/cxgb3
      usr/lib/firmware/cxgb3/ael2005_opt_edc.bin
      usr/lib/firmware/cxgb3/ael2005_twx_edc.bin
      usr/lib/firmware/cxgb3/ael2020_twx_edc.bin
      usr/lib/firmware/cxgb3/t3b_psram-1.1.0.bin
      usr/lib/firmware/cxgb3/t3c_psram-1.1.0.bin
      usr/lib/firmware/cxgb3/t3fw-7.12.0.bin
      usr/lib/firmware/cxgb4
      usr/lib/firmware/cxgb4/t4fw-1.26.6.0.bin
      usr/lib/firmware/cxgb4/t4fw.bin
      usr/lib/firmware/cxgb4/t5fw-1.26.6.0.bin
      usr/lib/firmware/cxgb4/t5fw.bin
      usr/lib/firmware/cxgb4/t6fw-1.26.6.0.bin
      usr/lib/firmware/cxgb4/t6fw.bin
      usr/lib/firmware/e100
      usr/lib/firmware/e100/d101m_ucode.bin
      usr/lib/firmware/e100/d101s_ucode.bin
      usr/lib/firmware/e100/d102e_ucode.bin
      usr/lib/firmware/ene-ub6250
      usr/lib/firmware/ene-ub6250/ms_init.bin
      usr/lib/firmware/ene-ub6250/ms_rdwr.bin
      usr/lib/firmware/ene-ub6250/msp_rdwr.bin
      usr/lib/firmware/ene-ub6250/sd_init1.bin
      usr/lib/firmware/ene-ub6250/sd_init2.bin
      usr/lib/firmware/ene-ub6250/sd_rdwr.bin
      usr/lib/firmware/intel
      usr/lib/firmware/intel/ice
      usr/lib/firmware/intel/ice/ddp
      usr/lib/firmware/intel/ice/ddp/ice-1.3.26.0.pkg
      usr/lib/firmware/intel/ice/ddp/ice.pkg
      usr/lib/firmware/isci
      usr/lib/firmware/isci/isci_firmware.bin
      usr/lib/firmware/kaweth
      usr/lib/firmware/kaweth/new_code.bin
      usr/lib/firmware/kaweth/new_code_fix.bin
      usr/lib/firmware/kaweth/trigger_code.bin
      usr/lib/firmware/kaweth/trigger_code_fix.bin
      usr/lib/firmware/liquidio
      usr/lib/firmware/liquidio/lio_210nv_nic.bin
      usr/lib/firmware/liquidio/lio_210sv_nic.bin
      usr/lib/firmware/liquidio/lio_23xx_nic.bin
      usr/lib/firmware/liquidio/lio_410nv_nic.bin
      usr/lib/firmware/mellanox
      usr/lib/firmware/mellanox/mlxsw_spectrum-13.2008.2406.mfa2
      usr/lib/firmware/mellanox/mlxsw_spectrum2-29.2008.2406.mfa2
      usr/lib/firmware/mellanox/mlxsw_spectrum3-30.2008.2406.mfa2
      usr/lib/firmware/myri10ge_eth_z8e.dat
      usr/lib/firmware/myri10ge_ethp_z8e.dat
      usr/lib/firmware/myri10ge_rss_eth_z8e.dat
      usr/lib/firmware/myri10ge_rss_ethp_z8e.dat
      usr/lib/firmware/netronome
      usr/lib/firmware/netronome/nic
      usr/lib/firmware/netronome/nic/nic_AMDA0058-0011_2x40.nffw
      usr/lib/firmware/netronome/nic/nic_AMDA0058-0012_2x40.nffw
      usr/lib/firmware/netronome/nic/nic_AMDA0081-0001_1x40.nffw
      usr/lib/firmware/netronome/nic/nic_AMDA0081-0001_4x10.nffw
      usr/lib/firmware/netronome/nic/nic_AMDA0096-0001_2x10.nffw
      usr/lib/firmware/netronome/nic/nic_AMDA0097-0001_2x40.nffw
      usr/lib/firmware/netronome/nic/nic_AMDA0097-0001_4x10_1x40.nffw
      usr/lib/firmware/netronome/nic/nic_AMDA0097-0001_8x10.nffw
      usr/lib/firmware/netronome/nic/nic_AMDA0099-0001_1x10_1x25.nffw
      usr/lib/firmware/netronome/nic/nic_AMDA0099-0001_2x10.nffw
      usr/lib/firmware/netronome/nic/nic_AMDA0099-0001_2x25.nffw
      usr/lib/firmware/netronome/nic_AMDA0058-0011_2x40.nffw
      usr/lib/firmware/netronome/nic_AMDA0058-0012_2x40.nffw
      usr/lib/firmware/netronome/nic_AMDA0081-0001_1x40.nffw
      usr/lib/firmware/netronome/nic_AMDA0081-0001_4x10.nffw
      usr/lib/firmware/netronome/nic_AMDA0096-0001_2x10.nffw
      usr/lib/firmware/netronome/nic_AMDA0097-0001_2x40.nffw
      usr/lib/firmware/netronome/nic_AMDA0097-0001_4x10_1x40.nffw
      usr/lib/firmware/netronome/nic_AMDA0097-0001_8x10.nffw
      usr/lib/firmware/netronome/nic_AMDA0099-0001_1x10_1x25.nffw
      usr/lib/firmware/netronome/nic_AMDA0099-0001_2x10.nffw
      usr/lib/firmware/netronome/nic_AMDA0099-0001_2x25.nffw
      usr/lib/firmware/ositech
      usr/lib/firmware/ositech/Xilinx7OD.bin
      usr/lib/firmware/phanfw.bin
      usr/lib/firmware/qed
      usr/lib/firmware/qed/qed_init_values_zipped-8.42.2.0.bin
      usr/lib/firmware/ql2100_fw.bin
      usr/lib/firmware/ql2200_fw.bin
      usr/lib/firmware/ql2300_fw.bin
      usr/lib/firmware/ql2322_fw.bin
      usr/lib/firmware/ql2400_fw.bin
      usr/lib/firmware/ql2500_fw.bin
      usr/lib/firmware/qlogic
      usr/lib/firmware/qlogic/1040.bin
      usr/lib/firmware/qlogic/12160.bin
      usr/lib/firmware/qlogic/1280.bin
      usr/lib/firmware/rtl_nic
      usr/lib/firmware/rtl_nic/rtl8105e-1.fw
      usr/lib/firmware/rtl_nic/rtl8106e-1.fw
      usr/lib/firmware/rtl_nic/rtl8106e-2.fw
      usr/lib/firmware/rtl_nic/rtl8107e-1.fw
      usr/lib/firmware/rtl_nic/rtl8107e-2.fw
      usr/lib/firmware/rtl_nic/rtl8125a-3.fw
      usr/lib/firmware/rtl_nic/rtl8125b-2.fw
      usr/lib/firmware/rtl_nic/rtl8153a-2.fw
      usr/lib/firmware/rtl_nic/rtl8153a-3.fw
      usr/lib/firmware/rtl_nic/rtl8153a-4.fw
      usr/lib/firmware/rtl_nic/rtl8153b-2.fw
      usr/lib/firmware/rtl_nic/rtl8153c-1.fw
      usr/lib/firmware/rtl_nic/rtl8156a-2.fw
      usr/lib/firmware/rtl_nic/rtl8156b-2.fw
      usr/lib/firmware/rtl_nic/rtl8168d-1.fw
      usr/lib/firmware/rtl_nic/rtl8168d-2.fw
      usr/lib/firmware/rtl_nic/rtl8168e-1.fw
      usr/lib/firmware/rtl_nic/rtl8168e-2.fw
      usr/lib/firmware/rtl_nic/rtl8168e-3.fw
      usr/lib/firmware/rtl_nic/rtl8168f-1.fw
      usr/lib/firmware/rtl_nic/rtl8168f-2.fw
      usr/lib/firmware/rtl_nic/rtl8168fp-3.fw
      usr/lib/firmware/rtl_nic/rtl8168g-2.fw
      usr/lib/firmware/rtl_nic/rtl8168g-3.fw
      usr/lib/firmware/rtl_nic/rtl8168h-1.fw
      usr/lib/firmware/rtl_nic/rtl8168h-2.fw
      usr/lib/firmware/rtl_nic/rtl8402-1.fw
      usr/lib/firmware/rtl_nic/rtl8411-1.fw
      usr/lib/firmware/rtl_nic/rtl8411-2.fw
      usr/lib/firmware/slicoss
      usr/lib/firmware/slicoss/gbdownload.sys
      usr/lib/firmware/slicoss/gbrcvucode.sys
      usr/lib/firmware/slicoss/oasisdownload.sys
      usr/lib/firmware/slicoss/oasisrcvucode.sys
      usr/lib/firmware/sun
      usr/lib/firmware/sun/cassini.bin
      usr/lib/firmware/tehuti
      usr/lib/firmware/tehuti/bdx.bin
      usr/lib/firmware/tigon
      usr/lib/firmware/tigon/tg3.bin
      usr/lib/firmware/tigon/tg3_tso.bin
      usr/lib/firmware/tigon/tg3_tso5.bin
      usr/lib/firmware/vxge
      usr/lib/firmware/vxge/X3fw-pxe.ncf
      usr/lib/firmware/vxge/X3fw.ncf
      usr/lib/initramfs-tools
      usr/lib/initramfs-tools/bin
      usr/lib/initramfs-tools/bin/gcc_s1-stub
      usr/lib/klibc-K8e6DOmVI9JpyGMLR7qNe5iZeBk.so
      usr/lib/modprobe.d
      usr/lib/modprobe.d/aliases.conf
      usr/lib/modprobe.d/blacklist_linux_5.15.0-25-generic.conf
      usr/lib/modprobe.d/fbdev-blacklist.conf
      usr/lib/modprobe.d/systemd.conf
      usr/lib/modules
      usr/lib/modules/5.15.0-25-generic
      usr/lib/modules/5.15.0-25-generic/kernel
      usr/lib/modules/5.15.0-25-generic/kernel/arch
      usr/lib/modules/5.15.0-25-generic/kernel/arch/x86
      usr/lib/modules/5.15.0-25-generic/kernel/arch/x86/crypto
      usr/lib/modules/5.15.0-25-generic/kernel/arch/x86/crypto/blake2s-x86_64.ko
      usr/lib/modules/5.15.0-25-generic/kernel/arch/x86/crypto/chacha-x86_64.ko
      usr/lib/modules/5.15.0-25-generic/kernel/arch/x86/crypto/crc32-pclmul.ko
      usr/lib/modules/5.15.0-25-generic/kernel/arch/x86/crypto/curve25519-x86_64.ko
      usr/lib/modules/5.15.0-25-generic/kernel/arch/x86/crypto/poly1305-x86_64.ko
      usr/lib/modules/5.15.0-25-generic/kernel/crypto
      usr/lib/modules/5.15.0-25-generic/kernel/crypto/blake2b_generic.ko
      usr/lib/modules/5.15.0-25-generic/kernel/crypto/crc32_generic.ko
      usr/lib/modules/5.15.0-25-generic/kernel/crypto/xor.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/acpi
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/acpi/platform_profile.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/acpi/video.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/acard-ahci.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/ahci.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/ahci_platform.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/libahci.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/libahci_platform.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_acpi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_ali.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_amd.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_artop.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_atiixp.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_atp867x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_cmd640.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_cmd64x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_cypress.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_efar.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_hpt366.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_hpt37x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_hpt3x2n.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_hpt3x3.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_it8213.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_it821x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_jmicron.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_legacy.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_marvell.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_mpiix.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_netcell.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_ninja32.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_ns87410.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_ns87415.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_oldpiix.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_opti.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_optidma.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_pcmcia.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_pdc2027x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_pdc202xx_old.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_piccolo.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_platform.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_radisys.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_rdc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_rz1000.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_sch.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_serverworks.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_sil680.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_sl82c105.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_triflex.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pata_via.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/pdc_adma.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/sata_dwc_460ex.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/sata_inic162x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/sata_mv.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/sata_nv.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/sata_promise.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/sata_qstor.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/sata_sil.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/sata_sil24.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/sata_sis.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/sata_svw.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/sata_sx4.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/sata_uli.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/sata_via.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ata/sata_vsc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/base
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/base/regmap
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/base/regmap/regmap-slimbus.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/base/regmap/regmap-spi-avmm.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/base/regmap/regmap-spmi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/bcma
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/bcma/bcma.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/aoe
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/aoe/aoe.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/brd.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/cryptoloop.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/drbd
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/drbd/drbd.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/floppy.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/mtip32xx
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/mtip32xx/mtip32xx.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/nbd.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/null_blk
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/null_blk/null_blk.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/paride
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/paride/aten.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/paride/bpck.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/paride/comm.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/paride/dstr.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/paride/epat.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/paride/epia.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/paride/fit2.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/paride/fit3.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/paride/friq.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/paride/frpw.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/paride/kbic.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/paride/ktti.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/paride/on20.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/paride/on26.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/paride/paride.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/paride/pcd.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/paride/pd.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/paride/pf.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/paride/pg.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/paride/pt.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/pktcdvd.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/rbd.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/rnbd
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/rnbd/rnbd-client.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/rnbd/rnbd-server.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/rsxx
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/rsxx/rsxx.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/sx8.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/virtio_blk.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/xen-blkback
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/xen-blkback/xen-blkback.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/zram
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/block/zram/zram.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/bus
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/bus/mhi
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/bus/mhi/core
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/bus/mhi/core/mhi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/bus/mhi/mhi_pci_generic.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/clk
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/clk/clk-cdce706.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/clk/clk-cs2000-cp.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/clk/clk-lmk04832.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/clk/clk-max9485.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/clk/clk-palmas.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/clk/clk-pwm.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/clk/clk-si5341.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/clk/clk-si5351.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/clk/clk-si544.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/clk/clk-twl6040.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/clk/clk-wm831x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/clk/xilinx
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/clk/xilinx/xlnx_vcu.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/dca
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/dca/dca.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/dma
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/dma/dw
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/dma/dw/dw_dmac.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/dma/dw/dw_dmac_core.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/dma/idma64.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/extcon
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/extcon/extcon-usb-gpio.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/extcon/extcon-usbc-cros-ec.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/firewire
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/firewire/firewire-core.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/firewire/firewire-ohci.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/firewire/firewire-sbp2.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/fpga
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/fpga/dfl.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/fpga/fpga-bridge.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/fpga/fpga-mgr.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/fpga/fpga-region.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-104-dio-48e.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-104-idi-48.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-104-idio-16.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-aaeon.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-adp5520.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-adp5588.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-aggregator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-amd-fch.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-amd8111.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-amdpt.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-arizona.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-bd9571mwv.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-da9052.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-da9055.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-dln2.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-dwapb.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-exar.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-f7188x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-generic.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-gpio-mm.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-ich.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-it87.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-janz-ttl.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-kempld.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-lp3943.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-lp873x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-madera.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-max3191x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-max7300.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-max7301.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-max730x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-max732x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-mb86s7x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-mc33880.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-menz127.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-ml-ioh.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-pca953x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-pca9570.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-pcf857x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-pci-idio-16.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-pcie-idio-24.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-pisosr.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-rdc321x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-sch.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-sch311x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-siox.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-tpic2810.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-tps65086.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-tps65912.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-tqmx86.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-twl4030.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-twl6040.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-ucb1400.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-viperboard.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-virtio.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-vx855.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-wcove.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-winbond.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-wm831x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-wm8350.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-wm8994.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-ws16c48.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/gpio/gpio-xra1403.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/amd-sfh-hid
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/amd-sfh-hid/amd_sfh.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-accutouch.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-alps.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-apple.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-appleir.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-asus.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-aureal.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-belkin.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-cherry.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-chicony.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-cmedia.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-corsair.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-cougar.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-cp2112.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-creative-sb0540.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-elan.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-elo.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-ezkey.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-ft260.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-gembird.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-generic.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-gfrm.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-glorious.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-google-hammer.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-gt683r.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-holtek-kbd.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-holtek-mouse.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-hyperv.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-ite.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-jabra.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-keytouch.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-led.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-lenovo.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-lg-g15.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-logitech-dj.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-logitech-hidpp.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-logitech.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-macally.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-maltron.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-mcp2221.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-mf.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-microsoft.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-monterey.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-nti.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-ortek.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-penmount.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-plantronics.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-playstation.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-primax.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-prodikeys.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-redragon.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-retrode.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-rmi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-roccat-arvo.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-roccat-common.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-roccat-isku.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-roccat-lua.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-roccat-ryos.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-roccat-savu.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-roccat.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-samsung.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-semitek.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-sensor-custom.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-sensor-hub.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-sjoy.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-steam.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-steelseries.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-sunplus.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-thrustmaster.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-topseed.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-u2fzero.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-udraw-ps3.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-viewsonic.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-vivaldi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid-xinmo.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/hid.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/i2c-hid
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/i2c-hid/i2c-hid-acpi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/i2c-hid/i2c-hid.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/intel-ish-hid
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/intel-ish-hid/intel-ish-ipc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/intel-ish-hid/intel-ishtp-hid.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/intel-ish-hid/intel-ishtp-loader.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/intel-ish-hid/intel-ishtp.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/surface-hid
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/surface-hid/surface_hid.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/surface-hid/surface_hid_core.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/surface-hid/surface_kbd.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/uhid.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/usbhid
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/usbhid/usbhid.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/usbhid/usbkbd.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/usbhid/usbmouse.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hid/wacom.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hv
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hv/hv_utils.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/hv/hv_vmbus.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/algos
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/algos/i2c-algo-bit.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/algos/i2c-algo-pca.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-ali1535.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-ali1563.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-ali15x3.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-amd-mp2-pci.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-amd-mp2-plat.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-amd756-s4882.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-amd756.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-amd8111.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-cbus-gpio.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-cht-wc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-cp2615.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-cros-ec-tunnel.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-designware-pci.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-diolan-u2c.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-dln2.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-gpio.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-i801.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-isch.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-ismt.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-kempld.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-mlxcpld.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-nforce2-s4985.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-nforce2.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-nvidia-gpu.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-ocores.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-parport.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-pca-platform.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-piix4.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-robotfuzz-osif.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-scmi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-simtec.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-sis5595.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-sis630.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-sis96x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-taos-evm.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-tiny-usb.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-via.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-viapro.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-viperboard.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-virtio.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/busses/i2c-xiic.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/i2c-mux.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/i2c-smbus.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/muxes
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/muxes/i2c-mux-gpio.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/muxes/i2c-mux-ltc4306.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/muxes/i2c-mux-mlxcpld.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/muxes/i2c-mux-pca9541.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/muxes/i2c-mux-pca954x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/i2c/muxes/i2c-mux-reg.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/iio
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/iio/common
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/iio/common/hid-sensors
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/iio/common/hid-sensors/hid-sensor-iio-common.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/iio/industrialio.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/infiniband
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/infiniband/core
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/infiniband/core/ib_cm.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/infiniband/core/ib_core.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/infiniband/core/ib_uverbs.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/infiniband/core/iw_cm.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/infiniband/core/rdma_cm.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/infiniband/hw
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/infiniband/hw/mlx4
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/infiniband/hw/mlx4/mlx4_ib.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/infiniband/hw/mlx5
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/infiniband/hw/mlx5/mlx5_ib.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/infiniband/ulp
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/infiniband/ulp/rtrs
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/infiniband/ulp/rtrs/rtrs-client.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/infiniband/ulp/rtrs/rtrs-core.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/infiniband/ulp/rtrs/rtrs-server.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/ff-memless.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/keyboard
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/keyboard/adc-keys.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/keyboard/adp5520-keys.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/keyboard/adp5588-keys.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/keyboard/adp5589-keys.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/keyboard/applespi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/keyboard/cros_ec_keyb.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/keyboard/dlink-dir685-touchkeys.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/keyboard/gpio_keys.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/keyboard/gpio_keys_polled.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/keyboard/iqs62x-keys.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/keyboard/lkkbd.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/keyboard/lm8323.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/keyboard/lm8333.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/keyboard/matrix_keypad.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/keyboard/max7359_keypad.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/keyboard/mcs_touchkey.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/keyboard/mpr121_touchkey.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/keyboard/mtk-pmic-keys.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/keyboard/newtonkbd.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/keyboard/opencores-kbd.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/keyboard/qt1050.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/keyboard/qt1070.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/keyboard/qt2160.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/keyboard/samsung-keypad.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/keyboard/stowaway.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/keyboard/sunkbd.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/keyboard/tca6416-keypad.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/keyboard/tca8418_keypad.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/keyboard/tm2-touchkey.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/keyboard/twl4030_keypad.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/keyboard/xtkbd.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/matrix-keymap.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/mouse
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/mouse/psmouse.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/rmi4
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/rmi4/rmi_core.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/serio
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/serio/hyperv-keyboard.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/input/sparse-keymap.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mcb
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mcb/mcb.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/media
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/media/common
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/media/common/videobuf2
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/media/common/videobuf2/videobuf2-common.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/media/common/videobuf2/videobuf2-memops.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/media/common/videobuf2/videobuf2-v4l2.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/media/common/videobuf2/videobuf2-vmalloc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/media/mc
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/media/mc/mc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/media/v4l2-core
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/media/v4l2-core/videodev.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/message
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/message/fusion
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/message/fusion/mptbase.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/message/fusion/mptfc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/message/fusion/mptsas.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/message/fusion/mptscsih.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/message/fusion/mptspi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/88pm800.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/88pm805.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/88pm80x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/arizona-i2c.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/arizona-spi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/arizona.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/atc260x-core.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/atc260x-i2c.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/axp20x-i2c.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/axp20x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/bcm590xx.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/bd9571mwv.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/cros_ec_dev.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/da9062-core.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/da9150-core.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/dln2.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/htc-pasic3.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/intel-lpss-acpi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/intel-lpss-pci.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/intel-lpss.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/intel-m10-bmc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/intel_pmc_bxt.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/intel_pmt.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/intel_quark_i2c_gpio.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/intel_soc_pmic_bxtwc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/intel_soc_pmic_chtdc_ti.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/intel_soc_pmic_mrfld.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/iqs62x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/janz-cmodio.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/kempld-core.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/lm3533-core.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/lm3533-ctrlbank.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/lp3943.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/lp873x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/lpc_ich.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/lpc_sch.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/madera-i2c.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/madera-spi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/madera.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/max8907.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/mc13xxx-core.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/mc13xxx-i2c.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/mc13xxx-spi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/menf21bmc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/mfd-aaeon.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/mp2629.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/mt6360-core.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/mt6397.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/pcf50633-adc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/pcf50633-gpio.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/pcf50633.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/rave-sp.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/rdc321x-southbridge.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/retu-mfd.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/rt4831.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/rt5033.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/si476x-core.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/sky81452.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/sm501.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/ti-lmu.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/ti_am335x_tscadc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/tps6105x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/tps65010.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/tps6507x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/tps65086.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/tqmx86.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/ucb1400_core.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/viperboard.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/vx855.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/wcd934x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/wl1273-core.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mfd/wm8994.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/misc
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/misc/cardreader
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/misc/cardreader/alcor_pci.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/misc/cardreader/rtsx_pci.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/misc/cardreader/rtsx_usb.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/misc/cb710
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/misc/cb710/cb710.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/misc/eeprom
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/misc/eeprom/eeprom_93cx6.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/misc/enclosure.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/misc/tifm_core.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mmc
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mmc/core
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mmc/core/mmc_block.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mmc/core/sdio_uart.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mmc/host
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mmc/host/alcor.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mmc/host/cb710-mmc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mmc/host/cqhci.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mmc/host/mmc_spi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mmc/host/mtk-sd.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mmc/host/of_mmc_spi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mmc/host/rtsx_pci_sdmmc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mmc/host/rtsx_usb_sdmmc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mmc/host/sdhci-acpi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mmc/host/sdhci-pci.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mmc/host/sdhci-pltfm.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mmc/host/sdhci-xenon-driver.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mmc/host/sdhci.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mmc/host/sdhci_f_sdh30.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mmc/host/sdricoh_cs.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mmc/host/tifm_sd.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mmc/host/toshsd.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mmc/host/usdhi6rol0.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mmc/host/ushc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mmc/host/via-sdmmc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mmc/host/vub300.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mmc/host/wbsd.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mtd
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mtd/mtd.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mux
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/mux/mux-core.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/bareudp.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/caif
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/caif/caif_serial.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/caif/caif_virtio.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/b53
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/b53/b53_common.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/b53/b53_mdio.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/b53/b53_mmap.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/b53/b53_serdes.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/b53/b53_spi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/b53/b53_srab.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/bcm-sf2.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/hirschmann
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/hirschmann/hellcreek_sw.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/lan9303-core.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/lan9303_i2c.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/lan9303_mdio.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/lantiq_gswip.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/microchip
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/microchip/ksz8795.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/microchip/ksz8795_spi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/microchip/ksz8863_smi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/microchip/ksz9477.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/microchip/ksz9477_i2c.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/microchip/ksz9477_spi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/microchip/ksz_common.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/mt7530.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/mv88e6060.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/mv88e6xxx
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/mv88e6xxx/mv88e6xxx.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/ocelot
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/ocelot/mscc_seville.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/qca
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/qca/ar9331.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/qca8k.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/realtek-smi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/sja1105
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/sja1105/sja1105.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/vitesse-vsc73xx-core.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/vitesse-vsc73xx-platform.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/vitesse-vsc73xx-spi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/xrs700x
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/xrs700x/xrs700x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/xrs700x/xrs700x_i2c.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/dsa/xrs700x/xrs700x_mdio.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/eql.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/3com
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/3com/3c509.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/3com/3c574_cs.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/3com/3c589_cs.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/3com/3c59x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/3com/typhoon.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/8390
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/8390/8390.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/8390/axnet_cs.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/8390/ne2k-pci.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/8390/pcnet_cs.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/adaptec
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/adaptec/starfire.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/agere
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/agere/et131x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/alacritech
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/alacritech/slicoss.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/alteon
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/alteon/acenic.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/altera
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/altera/altera_tse.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/amazon
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/amazon/ena
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/amazon/ena/ena.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/amd
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/amd/amd8111e.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/amd/nmclan_cs.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/amd/pcnet32.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/amd/xgbe
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/amd/xgbe/amd-xgbe.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/aquantia
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/aquantia/atlantic
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/aquantia/atlantic/atlantic.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/atheros
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/atheros/alx
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/atheros/alx/alx.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/atheros/atl1c
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/atheros/atl1c/atl1c.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/atheros/atl1e
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/atheros/atl1e/atl1e.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/atheros/atlx
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/atheros/atlx/atl1.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/atheros/atlx/atl2.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/broadcom
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/broadcom/b44.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/broadcom/bcmsysport.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/broadcom/bnx2.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/broadcom/bnx2x
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/broadcom/bnx2x/bnx2x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/broadcom/bnxt
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/broadcom/bnxt/bnxt_en.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/broadcom/cnic.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/broadcom/genet
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/broadcom/genet/genet.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/broadcom/tg3.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/brocade
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/brocade/bna
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/brocade/bna/bna.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/cadence
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/cadence/macb.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/cadence/macb_pci.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/cavium
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/cavium/common
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/cavium/common/cavium_ptp.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/cavium/liquidio
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/cavium/liquidio/liquidio.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/cavium/liquidio/liquidio_vf.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/cavium/thunder
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/cavium/thunder/nicpf.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/cavium/thunder/nicvf.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/cavium/thunder/thunder_bgx.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/cavium/thunder/thunder_xcv.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/chelsio
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/chelsio/cxgb
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/chelsio/cxgb/cxgb.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/chelsio/cxgb3
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/chelsio/cxgb3/cxgb3.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/chelsio/cxgb4
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/chelsio/cxgb4/cxgb4.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/chelsio/cxgb4vf
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/chelsio/inline_crypto
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/chelsio/inline_crypto/ch_ipsec
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/chelsio/inline_crypto/ch_ipsec/ch_ipsec.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/chelsio/inline_crypto/ch_ktls
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/chelsio/inline_crypto/ch_ktls/ch_ktls.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/chelsio/libcxgb
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/chelsio/libcxgb/libcxgb.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/cisco
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/cisco/enic
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/cisco/enic/enic.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/dec
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/dec/tulip
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/dec/tulip/de2104x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/dec/tulip/de4x5.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/dec/tulip/dmfe.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/dec/tulip/tulip.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/dec/tulip/uli526x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/dec/tulip/winbond-840.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/dec/tulip/xircom_cb.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/dlink
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/dlink/dl2k.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/dlink/sundance.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/dnet.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/ec_bhf.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/emulex
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/emulex/benet
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/emulex/benet/be2net.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/ethoc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/fealnx.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/fujitsu
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/fujitsu/fmvj18x_cs.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/google
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/google/gve
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/google/gve/gve.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/huawei
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/huawei/hinic
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/huawei/hinic/hinic.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/intel
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/intel/e100.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/intel/e1000
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/intel/e1000/e1000.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/intel/e1000e
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/intel/e1000e/e1000e.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/intel/fm10k
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/intel/fm10k/fm10k.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/intel/i40e
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/intel/i40e/i40e.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/intel/iavf
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/intel/iavf/iavf.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/intel/ice
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/intel/ice/ice.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/intel/igb
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/intel/igb/igb.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/intel/igbvf
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/intel/igbvf/igbvf.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/intel/igc
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/intel/igc/igc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/intel/ixgb
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/intel/ixgb/ixgb.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/intel/ixgbe
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/intel/ixgbe/ixgbe.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/intel/ixgbevf
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/intel/ixgbevf/ixgbevf.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/jme.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/marvell
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/marvell/mvmdio.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/marvell/prestera
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/marvell/prestera/prestera.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/marvell/prestera/prestera_pci.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/marvell/skge.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/marvell/sky2.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/mellanox
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/mellanox/mlx4
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/mellanox/mlx4/mlx4_core.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/mellanox/mlx4/mlx4_en.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/mellanox/mlx5
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/mellanox/mlx5/core
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/mellanox/mlxfw
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/mellanox/mlxfw/mlxfw.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/mellanox/mlxsw
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/mellanox/mlxsw/mlxsw_core.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/mellanox/mlxsw/mlxsw_i2c.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/mellanox/mlxsw/mlxsw_minimal.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/mellanox/mlxsw/mlxsw_pci.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/mellanox/mlxsw/mlxsw_spectrum.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/micrel
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/micrel/ks8842.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/micrel/ks8851_common.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/micrel/ks8851_par.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/micrel/ks8851_spi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/micrel/ksz884x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/microchip
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/microchip/enc28j60.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/microchip/encx24j600-regmap.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/microchip/encx24j600.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/microchip/lan743x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/microsoft
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/microsoft/mana
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/microsoft/mana/mana.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/mscc
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/mscc/mscc_ocelot_switch_lib.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/myricom
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/myricom/myri10ge
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/myricom/myri10ge/myri10ge.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/natsemi
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/natsemi/natsemi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/natsemi/ns83820.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/neterion
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/neterion/s2io.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/neterion/vxge
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/neterion/vxge/vxge.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/netronome
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/netronome/nfp
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/netronome/nfp/nfp.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/ni
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/ni/nixge.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/nvidia
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/nvidia/forcedeth.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/packetengines
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/packetengines/hamachi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/packetengines/yellowfin.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/pensando
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/pensando/ionic
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/pensando/ionic/ionic.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/qlogic
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/qlogic/netxen
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/qlogic/netxen/netxen_nic.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/qlogic/qed
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/qlogic/qed/qed.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/qlogic/qede
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/qlogic/qede/qede.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/qlogic/qla3xxx.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/qlogic/qlcnic
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/qlogic/qlcnic/qlcnic.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/qualcomm
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/qualcomm/emac
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/qualcomm/emac/qcom-emac.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/qualcomm/rmnet
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/qualcomm/rmnet/rmnet.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/rdc
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/rdc/r6040.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/realtek
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/realtek/8139cp.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/realtek/8139too.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/realtek/atp.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/realtek/r8169.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/rocker
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/rocker/rocker.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/samsung
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/samsung/sxgbe
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/samsung/sxgbe/samsung-sxgbe.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/sfc
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/sfc/falcon
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/sfc/falcon/sfc-falcon.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/sfc/sfc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/silan
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/silan/sc92031.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/sis
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/sis/sis190.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/sis/sis900.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/smsc
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/smsc/epic100.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/smsc/smc91c92_cs.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/smsc/smsc911x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/smsc/smsc9420.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/stmicro
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/stmicro/stmmac
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac-pci.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac-platform.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/sun
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/sun/cassini.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/sun/niu.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/sun/sungem.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/sun/sunhme.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/synopsys
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/synopsys/dwc-xlgmac.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/tehuti
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/tehuti/tehuti.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/ti
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/ti/tlan.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/via
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/via/via-rhine.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/via/via-velocity.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/wiznet
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/wiznet/w5100-spi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/wiznet/w5100.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/wiznet/w5300.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/xilinx
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/xilinx/ll_temac.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/xilinx/xilinx_emac.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/xilinx/xilinx_emaclite.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/xircom
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ethernet/xircom/xirc2ps_cs.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/fddi
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/fddi/defxx.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/fddi/skfp
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/fddi/skfp/skfp.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/fjes
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/fjes/fjes.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/geneve.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/gtp.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/hyperv
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/hyperv/hv_netvsc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ieee802154
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ieee802154/adf7242.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ieee802154/at86rf230.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ieee802154/atusb.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ieee802154/ca8210.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ieee802154/cc2520.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ieee802154/fakelb.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ieee802154/mac802154_hwsim.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ieee802154/mcr20a.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ieee802154/mrf24j40.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ipvlan
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ipvlan/ipvlan.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ipvlan/ipvtap.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/macsec.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/mdio
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/mdio.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/mdio/mdio-bcm-unimac.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/mdio/mdio-bitbang.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/mdio/mdio-cavium.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/mdio/mdio-gpio.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/mdio/mdio-i2c.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/mdio/mdio-mscc-miim.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/mdio/mdio-mvusb.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/mdio/mdio-thunder.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/mhi_net.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/mii.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/net_failover.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/netconsole.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/netdevsim
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/netdevsim/netdevsim.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/nlmon.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ntb_netdev.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/pcs
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/pcs/pcs-lynx.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/pcs/pcs_xpcs.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/adin.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/amd.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/aquantia.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/at803x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/ax88796b.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/bcm-phy-lib.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/bcm54140.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/bcm7xxx.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/bcm87xx.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/broadcom.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/cicada.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/cortina.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/davicom.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/dp83640.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/dp83822.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/dp83848.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/dp83867.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/dp83869.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/dp83tc811.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/et1011c.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/icplus.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/intel-xway.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/lxt.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/marvell-88x2222.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/marvell.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/marvell10g.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/mediatek-ge.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/micrel.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/microchip.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/microchip_t1.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/motorcomm.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/mscc
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/mscc/mscc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/mxl-gpy.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/national.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/nxp-c45-tja11xx.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/nxp-tja11xx.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/phylink.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/qsemi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/realtek.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/rockchip.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/sfp.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/smsc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/spi_ks8995.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/ste10Xp.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/teranetics.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/uPD60620.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/vitesse.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/phy/xilinx_gmii2rgmii.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/plip
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/plip/plip.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ppp
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ppp/bsd_comp.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ppp/ppp_async.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ppp/ppp_deflate.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ppp/ppp_mppe.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ppp/ppp_synctty.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ppp/pppoe.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ppp/pppox.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/ppp/pptp.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/rionet.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/slip
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/slip/slip.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/sungem_phy.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/tap.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/thunderbolt-net.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/usb
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/usb/aqc111.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/usb/asix.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/usb/ax88179_178a.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/usb/catc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/usb/cdc_eem.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/usb/cdc_ether.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/usb/cdc_ncm.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/usb/ch9200.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/usb/dm9601.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/usb/int51x1.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/usb/kaweth.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/usb/lan78xx.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/usb/mcs7830.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/usb/pegasus.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/usb/r8152.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/usb/r8153_ecm.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/usb/rndis_host.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/usb/rtl8150.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/usb/smsc75xx.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/usb/smsc95xx.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/usb/sr9700.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/usb/sr9800.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/usb/usbnet.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/virtio_net.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/vmxnet3
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/vmxnet3/vmxnet3.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/vrf.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/vsockmon.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/vxlan.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/wireguard
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/wireguard/wireguard.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/wwan
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/wwan/iosm
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/wwan/iosm/iosm.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/wwan/mhi_wwan_ctrl.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/wwan/mhi_wwan_mbim.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/wwan/rpmsg_wwan_ctrl.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/net/wwan/wwan_hwsim.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ntb
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ntb/ntb.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ntb/ntb_transport.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/nvme
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/nvme/host
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/nvme/host/nvme-core.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/nvme/host/nvme-fabrics.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/nvme/host/nvme-fc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/nvme/host/nvme-rdma.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/nvme/host/nvme-tcp.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/nvme/host/nvme.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/nvme/target
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/nvme/target/nvme-loop.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/nvme/target/nvmet-fc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/nvme/target/nvmet-rdma.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/nvme/target/nvmet-tcp.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/nvme/target/nvmet.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/parport
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/parport/parport.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/pci
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/pci/controller
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/pci/controller/pci-hyperv-intf.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/pci/controller/pci-hyperv.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/pci/controller/vmd.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/pcmcia
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/pcmcia/pcmcia.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/pcmcia/pcmcia_core.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/phy
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/phy/broadcom
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/phy/broadcom/phy-bcm-kona-usb2.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/phy/intel
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/phy/intel/phy-intel-lgm-emmc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/phy/marvell
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/phy/marvell/phy-pxa-28nm-hsic.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/phy/marvell/phy-pxa-28nm-usb2.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/phy/motorola
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/phy/motorola/phy-cpcap-usb.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/phy/phy-can-transceiver.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/phy/phy-lgm-usb.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/phy/qualcomm
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/phy/qualcomm/phy-qcom-usb-hs.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/phy/qualcomm/phy-qcom-usb-hsic.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/phy/samsung
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/phy/samsung/phy-exynos-usb2.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/phy/ti
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/phy/ti/phy-tusb1210.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/pinctrl
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/pinctrl/cirrus
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/pinctrl/cirrus/pinctrl-madera.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/pinctrl/intel
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/pinctrl/intel/pinctrl-alderlake.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/pinctrl/intel/pinctrl-broxton.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/pinctrl/intel/pinctrl-cannonlake.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/pinctrl/intel/pinctrl-cedarfork.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/pinctrl/intel/pinctrl-denverton.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/pinctrl/intel/pinctrl-elkhartlake.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/pinctrl/intel/pinctrl-emmitsburg.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/pinctrl/intel/pinctrl-geminilake.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/pinctrl/intel/pinctrl-icelake.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/pinctrl/intel/pinctrl-jasperlake.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/pinctrl/intel/pinctrl-lakefield.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/pinctrl/intel/pinctrl-lewisburg.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/pinctrl/intel/pinctrl-lynxpoint.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/pinctrl/intel/pinctrl-sunrisepoint.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/pinctrl/intel/pinctrl-tigerlake.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/pinctrl/pinctrl-da9062.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/pinctrl/pinctrl-mcp23s08.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/pinctrl/pinctrl-mcp23s08_i2c.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/pinctrl/pinctrl-mcp23s08_spi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/platform
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/platform/chrome
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/platform/chrome/cros_ec.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/platform/chrome/cros_ec_lpcs.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/platform/chrome/cros_ec_spi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/platform/chrome/wilco_ec
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/platform/chrome/wilco_ec/wilco_ec.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/platform/surface
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/platform/surface/aggregator
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/platform/surface/aggregator/surface_aggregator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/platform/x86
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/platform/x86/asus-wmi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/platform/x86/wmi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/power
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/power/supply
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/power/supply/axp20x_usb_power.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/pwm
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/pwm/pwm-cros-ec.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/88pg86x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/88pm800-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/88pm8607.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/aat2870-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/act8865-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/ad5398.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/arizona-ldo1.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/arizona-micsupp.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/as3711-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/atc260x-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/axp20x-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/bcm590xx-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/bd9571mwv-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/da903x-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/da9052-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/da9055-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/da9062-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/da9210-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/da9211-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/fan53555.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/fixed.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/gpio-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/isl6271a-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/isl9305.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/lm363x-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/lp3971.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/lp3972.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/lp872x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/lp8755.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/lp8788-buck.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/lp8788-ldo.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/ltc3589.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/ltc3676.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/max14577-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/max1586.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/max77693-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/max77826-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/max8649.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/max8660.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/max8893.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/max8907-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/max8925-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/max8952.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/max8997-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/max8998.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/mc13783-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/mc13892-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/mc13xxx-regulator-core.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/mp8859.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/mt6311-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/mt6315-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/mt6323-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/mt6358-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/mt6359-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/mt6360-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/mt6397-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/palmas-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/pca9450-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/pcap-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/pcf50633-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/pv88060-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/pv88080-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/pv88090-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/pwm-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/qcom-labibb-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/qcom_spmi-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/qcom_usb_vbus-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/rc5t583-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/rpi-panel-attiny-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/rt4801-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/rt4831-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/rt5033-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/rt6160-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/rt6245-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/rtmv20-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/rtq2134-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/rtq6752-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/sky81452-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/slg51000-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/tps51632-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/tps6105x-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/tps62360-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/tps65023-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/tps6507x-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/tps65086-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/tps65090-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/tps65132-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/tps6524x-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/tps6586x-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/tps65910-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/tps65912-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/tps80031-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/twl-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/twl6030-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/userspace-consumer.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/virtual.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/wm831x-dcdc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/wm831x-isink.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/wm831x-ldo.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/wm8350-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/wm8400-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/regulator/wm8994-regulator.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/reset
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/reset/reset-ti-syscon.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rpmsg
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rpmsg/rpmsg_core.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-88pm80x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-88pm860x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-ab-b5ze-s3.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-ab-eoz9.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-abx80x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-bq32k.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-bq4802.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-cros-ec.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-da9052.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-da9055.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-da9063.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-ds1286.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-ds1302.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-ds1305.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-ds1307.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-ds1343.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-ds1347.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-ds1374.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-ds1390.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-ds1511.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-ds1553.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-ds1672.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-ds1685.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-ds1742.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-ds2404.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-ds3232.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-em3027.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-fm3130.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-ftrtc010.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-goldfish.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-hid-sensor-time.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-isl12022.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-isl1208.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-lp8788.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-m41t80.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-m41t93.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-m41t94.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-m48t35.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-m48t59.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-m48t86.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-max6900.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-max6902.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-max6916.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-max8907.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-max8925.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-max8997.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-max8998.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-mc13xxx.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-mcp795.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-msm6242.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-mt6397.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-palmas.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-pcap.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-pcf2123.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-pcf2127.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-pcf50633.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-pcf85063.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-pcf8523.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-pcf85363.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-pcf8563.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-pcf8583.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-r9701.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-rc5t583.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-rp5c01.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-rs5c348.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-rs5c372.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-rv3028.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-rv3029c2.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-rv3032.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-rv8803.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-rx4581.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-rx6110.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-rx8010.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-rx8025.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-rx8581.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-s35390a.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-sd3078.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-stk17ta8.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-tps6586x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-tps65910.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-tps80031.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-v3020.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-wilco-ec.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-wm831x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-wm8350.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/rtc/rtc-x1205.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/3w-9xxx.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/3w-sas.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/3w-xxxx.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/53c700.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/BusLogic.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/a100u2w.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/aacraid
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/aacraid/aacraid.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/advansys.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/aha1740.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/aic7xxx
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/aic7xxx/aic79xx.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/aic7xxx/aic7xxx.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/aic94xx
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/aic94xx/aic94xx.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/am53c974.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/arcmsr
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/arcmsr/arcmsr.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/atp870u.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/be2iscsi
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/be2iscsi/be2iscsi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/bfa
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/bfa/bfa.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/bnx2fc
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/bnx2fc/bnx2fc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/bnx2i
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/bnx2i/bnx2i.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/ch.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/csiostor
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/csiostor/csiostor.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/cxgbi
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/cxgbi/cxgb3i
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/cxgbi/cxgb3i/cxgb3i.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/cxgbi/cxgb4i
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/cxgbi/cxgb4i/cxgb4i.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/cxgbi/libcxgbi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/dc395x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/device_handler
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/device_handler/scsi_dh_alua.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/device_handler/scsi_dh_emc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/device_handler/scsi_dh_hp_sw.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/device_handler/scsi_dh_rdac.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/dmx3191d.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/dpt_i2o.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/elx
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/elx/efct.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/esas2r
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/esas2r/esas2r.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/esp_scsi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/fcoe
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/fcoe/fcoe.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/fcoe/libfcoe.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/fdomain.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/fdomain_pci.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/fnic
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/fnic/fnic.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/hpsa.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/hptiop.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/hv_storvsc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/imm.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/initio.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/ipr.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/ips.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/isci
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/isci/isci.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/iscsi_boot_sysfs.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/iscsi_tcp.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/libfc
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/libfc/libfc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/libiscsi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/libiscsi_tcp.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/libsas
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/libsas/libsas.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/lpfc
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/lpfc/lpfc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/megaraid
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/megaraid.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/megaraid/megaraid_mbox.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/megaraid/megaraid_mm.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/megaraid/megaraid_sas.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/mpi3mr
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/mpi3mr/mpi3mr.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/mpt3sas
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/mpt3sas/mpt3sas.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/mvsas
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/mvsas/mvsas.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/mvumi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/myrb.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/myrs.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/pcmcia
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/pcmcia/aha152x_cs.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/pcmcia/fdomain_cs.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/pcmcia/qlogic_cs.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/pcmcia/sym53c500_cs.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/pm8001
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/pm8001/pm80xx.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/pmcraid.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/ppa.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/qedf
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/qedf/qedf.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/qedi
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/qedi/qedi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/qla1280.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/qla2xxx
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/qla2xxx/qla2xxx.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/qla2xxx/tcm_qla2xxx.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/qla4xxx
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/qla4xxx/qla4xxx.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/qlogicfas408.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/raid_class.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/scsi_debug.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/scsi_transport_fc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/scsi_transport_iscsi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/scsi_transport_sas.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/scsi_transport_spi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/scsi_transport_srp.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/ses.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/sim710.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/smartpqi
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/smartpqi/smartpqi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/snic
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/snic/snic.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/st.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/stex.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/sym53c8xx_2
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/sym53c8xx_2/sym53c8xx.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/ufs
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/ufs/cdns-pltfrm.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/ufs/tc-dwc-g210-pci.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/ufs/tc-dwc-g210-pltfrm.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/ufs/tc-dwc-g210.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/ufs/ufshcd-core.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/ufs/ufshcd-dwc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/ufs/ufshcd-pci.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/ufs/ufshcd-pltfrm.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/virtio_scsi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/vmw_pvscsi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/wd719x.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/scsi/xen-scsifront.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/siox
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/siox/siox-core.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/slimbus
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/slimbus/slimbus.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/spi
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/spi/spi-altera-core.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/spi/spi-altera-dfl.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/spi/spi-altera-platform.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/spi/spi-amd.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/spi/spi-axi-spi-engine.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/spi/spi-bitbang.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/spi/spi-butterfly.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/spi/spi-cadence.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/spi/spi-dln2.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/spi/spi-dw-mmio.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/spi/spi-dw-pci.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/spi/spi-dw.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/spi/spi-gpio.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/spi/spi-lantiq-ssc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/spi/spi-lm70llp.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/spi/spi-loopback-test.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/spi/spi-mux.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/spi/spi-mxic.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/spi/spi-nxp-fspi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/spi/spi-oc-tiny.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/spi/spi-pxa2xx-pci.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/spi/spi-pxa2xx-platform.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/spi/spi-sc18is602.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/spi/spi-sifive.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/spi/spi-slave-system-control.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/spi/spi-slave-time.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/spi/spi-tle62x0.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/spi/spi-xcomm.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/spi/spi-zynqmp-gqspi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/spi/spidev.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/spmi
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/spmi/spmi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ssb
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/ssb/ssb.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/target
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/target/target_core_mod.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/thunderbolt
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/thunderbolt/thunderbolt.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/uio
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/uio/uio.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/c67x00
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/c67x00/c67x00.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/chipidea
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/chipidea/ci_hdrc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/chipidea/ci_hdrc_msm.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/chipidea/ci_hdrc_pci.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/chipidea/ci_hdrc_usb2.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/common
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/common/ulpi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/dwc2
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/dwc2/dwc2_pci.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/dwc3
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/dwc3/dwc3-haps.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/dwc3/dwc3-pci.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/dwc3/dwc3.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/gadget
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/gadget/udc
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/gadget/udc/udc-core.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/host
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/host/bcma-hcd.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/host/ehci-fsl.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/host/fotg210-hcd.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/host/fsl-mph-dr-of.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/host/isp116x-hcd.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/host/max3421-hcd.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/host/oxu210hp-hcd.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/host/r8a66597-hcd.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/host/ssb-hcd.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/host/xhci-pci-renesas.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/host/xhci-pci.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/host/xhci-plat-hcd.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/isp1760
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/isp1760/isp1760.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/musb
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/musb/musb_hdrc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/phy
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/phy/phy-generic.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/phy/phy-gpio-vbus-usb.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/phy/phy-isp1301.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/phy/phy-tahvo.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/storage
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/storage/uas.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/storage/ums-alauda.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/storage/ums-cypress.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/storage/ums-datafab.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/storage/ums-eneub6250.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/storage/ums-freecom.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/storage/ums-isd200.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/storage/ums-jumpshot.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/storage/ums-karma.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/storage/ums-onetouch.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/storage/ums-realtek.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/storage/ums-sddr09.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/storage/ums-sddr55.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/storage/ums-usbat.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/usb/storage/usb-storage.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/vhost
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/vhost/vhost_iotlb.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/vhost/vringh.ko
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/video
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/video/backlight
      usr/lib/modules/5.15.0-25-generic/kernel/drivers/video/backlight/pwm_bl.ko
      usr/lib/modules/5.15.0-25-generic/kernel/fs
      usr/lib/modules/5.15.0-25-generic/kernel/fs/btrfs
      usr/lib/modules/5.15.0-25-generic/kernel/fs/btrfs/btrfs.ko
      usr/lib/modules/5.15.0-25-generic/kernel/fs/f2fs
      usr/lib/modules/5.15.0-25-generic/kernel/fs/f2fs/f2fs.ko
      usr/lib/modules/5.15.0-25-generic/kernel/fs/fscache
      usr/lib/modules/5.15.0-25-generic/kernel/fs/fscache/fscache.ko
      usr/lib/modules/5.15.0-25-generic/kernel/fs/isofs
      usr/lib/modules/5.15.0-25-generic/kernel/fs/isofs/isofs.ko
      usr/lib/modules/5.15.0-25-generic/kernel/fs/jfs
      usr/lib/modules/5.15.0-25-generic/kernel/fs/jfs/jfs.ko
      usr/lib/modules/5.15.0-25-generic/kernel/fs/lockd
      usr/lib/modules/5.15.0-25-generic/kernel/fs/lockd/lockd.ko
      usr/lib/modules/5.15.0-25-generic/kernel/fs/netfs
      usr/lib/modules/5.15.0-25-generic/kernel/fs/netfs/netfs.ko
      usr/lib/modules/5.15.0-25-generic/kernel/fs/nfs
      usr/lib/modules/5.15.0-25-generic/kernel/fs/nfs/nfs.ko
      usr/lib/modules/5.15.0-25-generic/kernel/fs/nfs/nfsv2.ko
      usr/lib/modules/5.15.0-25-generic/kernel/fs/nfs/nfsv3.ko
      usr/lib/modules/5.15.0-25-generic/kernel/fs/nfs/nfsv4.ko
      usr/lib/modules/5.15.0-25-generic/kernel/fs/nfs_common
      usr/lib/modules/5.15.0-25-generic/kernel/fs/nfs_common/grace.ko
      usr/lib/modules/5.15.0-25-generic/kernel/fs/nfs_common/nfs_acl.ko
      usr/lib/modules/5.15.0-25-generic/kernel/fs/nls
      usr/lib/modules/5.15.0-25-generic/kernel/fs/nls/nls_iso8859-1.ko
      usr/lib/modules/5.15.0-25-generic/kernel/fs/reiserfs
      usr/lib/modules/5.15.0-25-generic/kernel/fs/reiserfs/reiserfs.ko
      usr/lib/modules/5.15.0-25-generic/kernel/fs/udf
      usr/lib/modules/5.15.0-25-generic/kernel/fs/udf/udf.ko
      usr/lib/modules/5.15.0-25-generic/kernel/fs/xfs
      usr/lib/modules/5.15.0-25-generic/kernel/fs/xfs/xfs.ko
      usr/lib/modules/5.15.0-25-generic/kernel/lib
      usr/lib/modules/5.15.0-25-generic/kernel/lib/842
      usr/lib/modules/5.15.0-25-generic/kernel/lib/842/842_decompress.ko
      usr/lib/modules/5.15.0-25-generic/kernel/lib/crc-itu-t.ko
      usr/lib/modules/5.15.0-25-generic/kernel/lib/crc7.ko
      usr/lib/modules/5.15.0-25-generic/kernel/lib/crc8.ko
      usr/lib/modules/5.15.0-25-generic/kernel/lib/crypto
      usr/lib/modules/5.15.0-25-generic/kernel/lib/crypto/libarc4.ko
      usr/lib/modules/5.15.0-25-generic/kernel/lib/crypto/libblake2s-generic.ko
      usr/lib/modules/5.15.0-25-generic/kernel/lib/crypto/libblake2s.ko
      usr/lib/modules/5.15.0-25-generic/kernel/lib/crypto/libchacha.ko
      usr/lib/modules/5.15.0-25-generic/kernel/lib/crypto/libchacha20poly1305.ko
      usr/lib/modules/5.15.0-25-generic/kernel/lib/crypto/libcurve25519-generic.ko
      usr/lib/modules/5.15.0-25-generic/kernel/lib/libcrc32c.ko
      usr/lib/modules/5.15.0-25-generic/kernel/lib/lru_cache.ko
      usr/lib/modules/5.15.0-25-generic/kernel/lib/lz4
      usr/lib/modules/5.15.0-25-generic/kernel/lib/lz4/lz4_compress.ko
      usr/lib/modules/5.15.0-25-generic/kernel/lib/lz4/lz4hc_compress.ko
      usr/lib/modules/5.15.0-25-generic/kernel/lib/objagg.ko
      usr/lib/modules/5.15.0-25-generic/kernel/lib/parman.ko
      usr/lib/modules/5.15.0-25-generic/kernel/lib/raid6
      usr/lib/modules/5.15.0-25-generic/kernel/lib/raid6/raid6_pq.ko
      usr/lib/modules/5.15.0-25-generic/kernel/lib/zstd
      usr/lib/modules/5.15.0-25-generic/kernel/lib/zstd/zstd_compress.ko
      usr/lib/modules/5.15.0-25-generic/kernel/net
      usr/lib/modules/5.15.0-25-generic/kernel/net/802
      usr/lib/modules/5.15.0-25-generic/kernel/net/802/garp.ko
      usr/lib/modules/5.15.0-25-generic/kernel/net/802/mrp.ko
      usr/lib/modules/5.15.0-25-generic/kernel/net/802/stp.ko
      usr/lib/modules/5.15.0-25-generic/kernel/net/8021q
      usr/lib/modules/5.15.0-25-generic/kernel/net/8021q/8021q.ko
      usr/lib/modules/5.15.0-25-generic/kernel/net/bridge
      usr/lib/modules/5.15.0-25-generic/kernel/net/bridge/bridge.ko
      usr/lib/modules/5.15.0-25-generic/kernel/net/ceph
      usr/lib/modules/5.15.0-25-generic/kernel/net/ceph/libceph.ko
      usr/lib/modules/5.15.0-25-generic/kernel/net/core
      usr/lib/modules/5.15.0-25-generic/kernel/net/core/failover.ko
      usr/lib/modules/5.15.0-25-generic/kernel/net/dsa
      usr/lib/modules/5.15.0-25-generic/kernel/net/dsa/dsa_core.ko
      usr/lib/modules/5.15.0-25-generic/kernel/net/hsr
      usr/lib/modules/5.15.0-25-generic/kernel/net/hsr/hsr.ko
      usr/lib/modules/5.15.0-25-generic/kernel/net/ieee802154
      usr/lib/modules/5.15.0-25-generic/kernel/net/ieee802154/ieee802154.ko
      usr/lib/modules/5.15.0-25-generic/kernel/net/ipv4
      usr/lib/modules/5.15.0-25-generic/kernel/net/ipv4/gre.ko
      usr/lib/modules/5.15.0-25-generic/kernel/net/ipv4/udp_tunnel.ko
      usr/lib/modules/5.15.0-25-generic/kernel/net/ipv6
      usr/lib/modules/5.15.0-25-generic/kernel/net/ipv6/ip6_tunnel.ko
      usr/lib/modules/5.15.0-25-generic/kernel/net/ipv6/ip6_udp_tunnel.ko
      usr/lib/modules/5.15.0-25-generic/kernel/net/ipv6/tunnel6.ko
      usr/lib/modules/5.15.0-25-generic/kernel/net/llc
      usr/lib/modules/5.15.0-25-generic/kernel/net/llc/llc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/net/mac802154
      usr/lib/modules/5.15.0-25-generic/kernel/net/mac802154/mac802154.ko
      usr/lib/modules/5.15.0-25-generic/kernel/net/psample
      usr/lib/modules/5.15.0-25-generic/kernel/net/psample/psample.ko
      usr/lib/modules/5.15.0-25-generic/kernel/net/sched
      usr/lib/modules/5.15.0-25-generic/kernel/net/sched/sch_taprio.ko
      usr/lib/modules/5.15.0-25-generic/kernel/net/sunrpc
      usr/lib/modules/5.15.0-25-generic/kernel/net/sunrpc/sunrpc.ko
      usr/lib/modules/5.15.0-25-generic/kernel/net/tls
      usr/lib/modules/5.15.0-25-generic/kernel/net/tls/tls.ko
      usr/lib/modules/5.15.0-25-generic/kernel/net/vmw_vsock
      usr/lib/modules/5.15.0-25-generic/kernel/net/vmw_vsock/vsock.ko
      usr/lib/modules/5.15.0-25-generic/kernel/net/xfrm
      usr/lib/modules/5.15.0-25-generic/kernel/net/xfrm/xfrm_algo.ko
      usr/lib/modules/5.15.0-25-generic/kernel/sound
      usr/lib/modules/5.15.0-25-generic/kernel/sound/ac97_bus.ko
      usr/lib/modules/5.15.0-25-generic/kernel/sound/core
      usr/lib/modules/5.15.0-25-generic/kernel/sound/core/snd-compress.ko
      usr/lib/modules/5.15.0-25-generic/kernel/sound/core/snd-pcm-dmaengine.ko
      usr/lib/modules/5.15.0-25-generic/kernel/sound/core/snd-pcm.ko
      usr/lib/modules/5.15.0-25-generic/kernel/sound/core/snd-rawmidi.ko
      usr/lib/modules/5.15.0-25-generic/kernel/sound/core/snd-seq-device.ko
      usr/lib/modules/5.15.0-25-generic/kernel/sound/core/snd-timer.ko
      usr/lib/modules/5.15.0-25-generic/kernel/sound/core/snd.ko
      usr/lib/modules/5.15.0-25-generic/kernel/sound/soc
      usr/lib/modules/5.15.0-25-generic/kernel/sound/soc/snd-soc-core.ko
      usr/lib/modules/5.15.0-25-generic/kernel/sound/soundcore.ko
      usr/lib/modules/5.15.0-25-generic/modules.alias
      usr/lib/modules/5.15.0-25-generic/modules.alias.bin
      usr/lib/modules/5.15.0-25-generic/modules.builtin
      usr/lib/modules/5.15.0-25-generic/modules.builtin.alias.bin
      usr/lib/modules/5.15.0-25-generic/modules.builtin.bin
      usr/lib/modules/5.15.0-25-generic/modules.dep
      usr/lib/modules/5.15.0-25-generic/modules.dep.bin
      usr/lib/modules/5.15.0-25-generic/modules.devname
      usr/lib/modules/5.15.0-25-generic/modules.order
      usr/lib/modules/5.15.0-25-generic/modules.softdep
      usr/lib/modules/5.15.0-25-generic/modules.symbols
      usr/lib/modules/5.15.0-25-generic/modules.symbols.bin
      usr/lib/systemd
      usr/lib/systemd/network
      usr/lib/systemd/network/73-usb-net-by-mac.link
      usr/lib/systemd/network/99-default.link
      usr/lib/systemd/systemd-udevd
      usr/lib/udev
      usr/lib/udev/ata_id
      usr/lib/udev/rules.d
      usr/lib/udev/rules.d/50-firmware.rules
      usr/lib/udev/rules.d/50-udev-default.rules
      usr/lib/udev/rules.d/55-dm.rules
      usr/lib/udev/rules.d/60-block.rules
      usr/lib/udev/rules.d/60-persistent-storage-dm.rules
      usr/lib/udev/rules.d/60-persistent-storage.rules
      usr/lib/udev/rules.d/61-persistent-storage-android.rules
      usr/lib/udev/rules.d/71-seat.rules
      usr/lib/udev/rules.d/73-special-net-names.rules
      usr/lib/udev/rules.d/75-net-description.rules
      usr/lib/udev/rules.d/80-drivers.rules
      usr/lib/udev/rules.d/80-net-setup-link.rules
      usr/lib/udev/rules.d/95-dm-notify.rules
      usr/lib/udev/scsi_id
      usr/lib/x86_64-linux-gnu
      usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
      usr/lib/x86_64-linux-gnu/libacl.so.1
      usr/lib/x86_64-linux-gnu/libacl.so.1.1.2301
      usr/lib/x86_64-linux-gnu/libblkid.so.1
      usr/lib/x86_64-linux-gnu/libblkid.so.1.1.0
      usr/lib/x86_64-linux-gnu/libc.so.6
      usr/lib/x86_64-linux-gnu/libcap.so.2
      usr/lib/x86_64-linux-gnu/libcap.so.2.44
      usr/lib/x86_64-linux-gnu/libcom_err.so.2
      usr/lib/x86_64-linux-gnu/libcom_err.so.2.1
      usr/lib/x86_64-linux-gnu/libcrypto.so.3
      usr/lib/x86_64-linux-gnu/libdevmapper.so.1.02.1
      usr/lib/x86_64-linux-gnu/libdns-export.so.1110
      usr/lib/x86_64-linux-gnu/libdns-export.so.1110.0.2
      usr/lib/x86_64-linux-gnu/libe2p.so.2
      usr/lib/x86_64-linux-gnu/libe2p.so.2.3
      usr/lib/x86_64-linux-gnu/libext2fs.so.2
      usr/lib/x86_64-linux-gnu/libext2fs.so.2.4
      usr/lib/x86_64-linux-gnu/libgcc_s.so.1
      usr/lib/x86_64-linux-gnu/libisc-export.so.1105
      usr/lib/x86_64-linux-gnu/libisc-export.so.1105.0.2
      usr/lib/x86_64-linux-gnu/libkmod.so.2
      usr/lib/x86_64-linux-gnu/libkmod.so.2.3.7
      usr/lib/x86_64-linux-gnu/liblzma.so.5
      usr/lib/x86_64-linux-gnu/liblzma.so.5.2.5
      usr/lib/x86_64-linux-gnu/libm.so.6
      usr/lib/x86_64-linux-gnu/libnss_dns.so.2
      usr/lib/x86_64-linux-gnu/libnss_files.so.2
      usr/lib/x86_64-linux-gnu/libpcre2-8.so.0
      usr/lib/x86_64-linux-gnu/libpcre2-8.so.0.10.4
      usr/lib/x86_64-linux-gnu/libpthread.so.0
      usr/lib/x86_64-linux-gnu/libresolv.so.2
      usr/lib/x86_64-linux-gnu/libselinux.so.1
      usr/lib/x86_64-linux-gnu/libudev.so.1
      usr/lib/x86_64-linux-gnu/libudev.so.1.7.2
      usr/lib/x86_64-linux-gnu/libzstd.so.1
      usr/lib/x86_64-linux-gnu/libzstd.so.1.4.8
      usr/lib32
      usr/lib64
      usr/lib64/ld-linux-x86-64.so.2
      usr/libx32
      usr/sbin
      usr/sbin/blkid
      usr/sbin/dhclient
      usr/sbin/dhclient-script
      110945+1 records in
      110945+1 records out
      56804152 bytes (57 MB, 54 MiB) copied, 0.249625 s, 228 MB/s
      usr/sbin/dmsetup
      usr/sbin/dumpe2fs
      usr/sbin/modprobe
      usr/sbin/rmmod
      usr/sbin/wait-for-root
      var
      var/lib
      var/lib/dhcp
      371149 blocks
      
    这个有点太辛苦了,所以有大侠指出更容易感觉更复杂的做法是使用binwalk

四月二十五日 等待变化等待机会

  1. 先转回之前的网络设置。这里是使用NAT来配置虚拟网络,我比较看重它使用无线网络这一点,至少不至于把主机的主要网络都搞乱。第一步是安装dnsmasq,以前工作中接触到这款软件,总之我也很担心它和默认的systemd-resolv冲突
    
    $ journalctl -xeu dnsmasq.service
    Apr 25 06:38:25 nick-sager dnsmasq[80522]: dnsmasq: failed to create listening socket for 172.27.232.139: Address already in use
    Apr 25 06:38:25 nick-sager dnsmasq[80522]: failed to create listening socket for 172.27.232.139: Address already in use
    Apr 25 06:38:25 nick-sager systemd[1]: dnsmasq.service: Control process exited, code=exited, status=2/INVALIDARGUMENT
    
    我看到这个错误一开始并不明白,以为是帖子里的和systemd-resolv关于127.0.0.1:53:53的冲突,后来enable了/etc/dnsmasq.conf里的bind-interfaces依然不解决问题才意识到可能是我已经使用openvpn的tun0设置的这个dns的关系吧?
    
    nick@nick-sager:~/workspace/debootstrap/tmp/initrd$ ifconfig tun0
    tun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1500
            inet 172.27.232.139  netmask 255.255.248.0  destination 172.27.232.139
            unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 500  (UNSPEC)
            RX packets 29709  bytes 10335721 (10.3 MB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 28234  bytes 3116970 (3.1 MB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    也许我应该先配置我的NAT(Network Address Translation)之后再解决这个问题吧?我先下载这个脚本 可是且慢,我已经有一个/etc/qemu-ifup的脚本了,这个应该是qemu自带的,怎么办?
    1. 这个默认的脚本说
      
      # Script to bring a network (tap) device for qemu up.
      # The idea is to add the tap device to the same bridge
      # as we have default routing to.
      
    2. 首先是找出是否系统有ip或者brctl命令,如果有ipip link set "$1" up第一个参数应该是传入的设备名吧?
    3. 如果系统有brctl命令则把目标桥设备ip地址为0.0.0.0:
      
      ifconfig "$1" 0.0.0.0 up
      
    4. 接下来是找出默认的桥接的设备
      
      switch=$(ip route ls | \
          awk '/^default / {
                for(i=0;i<NF;i++) { if ($i == "dev") { print $(i+1); next; } }
               }'
              )
      $ echo $switch
      enp0s31f6
      
      理解这个命令需要先看看我的route table是如何的:
      
      $ ip route ls
      0.0.0.0/1 via 172.27.232.1 dev tun0 
      default via 192.168.1.1 dev enp0s31f6 proto dhcp metric 100 
      54.67.3.66 via 192.168.1.1 dev enp0s31f6 
      128.0.0.0/1 via 172.27.232.1 dev tun0 
      169.254.0.0/16 dev enp0s31f6 scope link metric 1000 
      172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown 
      172.27.232.0/21 dev tun0 proto kernel scope link src 172.27.232.139 
      192.168.1.0/24 dev enp0s31f6 proto kernel scope link src 192.168.1.11 metric 100
      
      而以上的命令是找出第一个dev的设备,这一点我估计就是dnsmasq的问题,它就是找route table第一个栏目的设备并不管它是不是桥接设备,所以,qemu-ifup的官方脚本找到的switch=enp0s31f6而不是默认的tun0
    5. 下面这一步的意图是这样子的
      
      # only add the interface to default-route bridge if we
      # have such interface (with default route) and if that
      # interface is actually a bridge.
      # It is possible to have several default routes too
      
      它的命令是什么呢?
      
      for br in $switch; do
          if [ -d /sys/class/net/$br/bridge/. ]; then
              if [ -n "$ip" ]; then
                ip link set "$1" master "$br"
              else
                brctl addif $br "$1"
              fi
              exit    # exit with status of the previous command
          fi
      done
      
      我把实际命令ip link set和brctl addif都改成echo来看看结果是什么,结果是空,因为很显然的/sys/class/net/enp0s31f6/bridge不存在,说明我们默认的route不是bridge,所以,不加它!
    总而言之,dnsmasq的启动错误不是和systemd-resolv的冲突,而是试图和我的openvpn创建的tun0设备抢夺?我之前的搜索找错了方向。
  2. 感觉我没有走在正确的道路上,dnsmasq仅仅是一个小的步骤,而且是否是必须的呢?需要绑定在这个service吗?重要的是tun/tap的配置上。所以,我先看看这个脚本说实在的,这个领域对于我这个网络新手是很让人抓狂的,因为看上去有很多的道路可走!
  3. 感觉非常多的线索,为了不漏掉先记录一下这个feature,它是可以自动设置tap和bridge的吗?还是我要手动配置?我的/etc/qemu/bridge.conf 配置是
    
    $ cat /etc/qemu/bridge.conf 
    allow virtbr0
    
    可是当我运行
    
    $ qemu-system-x86_64 -kernel tmp/vmlinuz-5.15.0-25-generic  -serial stdio -m 2G  -drive format=raw,file=ubuntu-efi-disk -append "root=PARTUUID=8613E0D8-6556-7A47-922D-EDA26D53D20B console=ttyS0 earlyprintk=ttyS0" -netdev tap,id=hn0,br=virtbr0 -device virtio-net-pci,netdev=hn0,id=nic1
    qemu-system-x86_64: -netdev tap,id=hn0,br=virtbr0: could not configure /dev/net/tun: Operation not permitted
    
    所以,这个是权限问题!这里有一个思路 但是我很怀疑这个是否必要,因为我的/dev/net/tun是所有人都可以读写的,这个在内核文档似乎提到过控制权限不在这里
    
    $ ll /dev/net/tun 
    crw-rw-rw- 1 root root 10, 200 Apr 19 15:01 /dev/net/tun
    
    而这位大侠说的很对,具体看打开这个文件后来做了什么
    
    strace -o qemu.strace qemu-system-x86_64 -kernel tmp/vmlinuz-5.15.0-25-generic  -serial stdio -m 2G  -drive format=raw,file=ubuntu-efi-disk -append "root=PARTUUID=8613E0D8-6556-7A47-922D-EDA26D53D20B console=ttyS0 earlyprintk=ttyS0" -netdev tap,id=hn0,br=virtbr0 -device virtio-net-pci,netdev=hn0,id=nic1
    
    结果输出在qemu.strace里,我们搜索打开文件的结果
    
    $ grep -A 3 /dev/net/tun qemu.strace 
    openat(AT_FDCWD, "/dev/net/tun", O_RDWR) = 14
    ioctl(14, TUNGETFEATURES, 0x7fffa04bc858) = 0
    ioctl(14, TUNSETVNETHDRSZ, 0x7fffa04bc85c) = -1 EBADFD (File descriptor in bad state)
    ioctl(14, TUNSETIFF, 0x7fffa04bc860)    = -1 EPERM (Operation not permitted)
    
    所以,很明显的,你就算让/dev/net/tun可以普通用户读写,你能把ioctl的权限加进去吗? 这里也许是部分解决了权限的问题:
    
    $ tunctl -t tap0 -g nick -u nick
    Set 'tap0' persistent and owned by uid 1000 gid 1000
    
    然后我启动的时候指定了我的tap设备
    
    qemu-system-x86_64 -kernel tmp/vmlinuz-5.15.0-25-generic  -serial stdio -m 2G  -drive format=raw,file=ubuntu-efi-disk -append "root=PARTUUID=8613E0D8-6556-7A47-922D-EDA26D53D20B console=ttyS0 earlyprintk=ttyS0" -netdev tap,ifname=tap0,id=hn0,br=virtbr0,script=no,downscript=no -device virtio-net-pci,netdev=hn0,id=nic1
    
    权限解决了,但是我的虚拟机网络没有设置好,看来我还是需要手动配置桥啊?感觉太乱了,这个是预想得到的,因为这里有至少两个不同的途径:bridge,tap
    
    -netdev tap,id=str[,fd=h][,fds=x:y:...:z][,ifname=name][,script=file][,downscript=dfile]
             [,br=bridge][,helper=helper][,sndbuf=nbytes][,vnet_hdr=on|off][,vhost=on|off]
             [,vhostfd=h][,vhostfds=x:y:...:z][,vhostforce=on|off][,queues=n]
             [,poll-us=n]
                    configure a host TAP network backend with ID 'str'
                    connected to a bridge (default=br0)
                    use network scripts 'file' (default=/etc/qemu-ifup)
                    to configure it and 'dfile' (default=/etc/qemu-ifdown)
                    to deconfigure it
                    use '[down]script=no' to disable script execution
                    use network helper 'helper' (default=/usr/lib/qemu/qemu-bridge-helper) to
                    configure it
                    use 'fd=h' to connect to an already opened TAP interface
                    use 'fds=x:y:...:z' to connect to already opened multiqueue capable TAP interfaces
                    use 'sndbuf=nbytes' to limit the size of the send buffer (the
                    default is disabled 'sndbuf=0' to enable flow control set 'sndbuf=1048576')
                    use vnet_hdr=off to avoid enabling the IFF_VNET_HDR tap flag
                    use vnet_hdr=on to make the lack of IFF_VNET_HDR support an error condition
                    use vhost=on to enable experimental in kernel accelerator
                        (only has effect for virtio guests which use MSIX)
                    use vhostforce=on to force vhost on for non-MSIX virtio guests
                    use 'vhostfd=h' to connect to an already opened vhost net device
                    use 'vhostfds=x:y:...:z to connect to multiple already opened vhost net devices
                    use 'queues=n' to specify the number of queues to be created for multiqueue TAP
                    use 'poll-us=n' to specify the maximum number of microseconds that could be
                    spent on busy polling for vhost net
    
    这么多的选项是关于tap的!而关于bridge怎么这么简单?
    
    -netdev bridge,id=str[,br=bridge][,helper=helper]
                    configure a host TAP network backend with ID 'str' that is
                    connected to a bridge (default=br0)
                    using the program 'helper (default=/usr/lib/qemu/qemu-bridge-helper)
    
    问题是我的bridge设好了吗?
    
    $ brctl show
    bridge name	bridge id		STP enabled	interfaces
    docker0		8000.024265d25948	no
    
    所以,你真的是在瞎忙一气!再确认一下
    
    $ networkctl
    WARNING: systemd-networkd is not running, output will be incomplete.
    
    IDX LINK      TYPE     OPERATIONAL SETUP    
      1 lo        loopback n/a         unmanaged
      2 enp0s31f6 ether    n/a         unmanaged
      3 wlp109s0  wlan     n/a         unmanaged
      5 docker0   bridge   n/a         unmanaged
     12 tun0      none     n/a         unmanaged
     13 tap0      ether    n/a         unmanaged
    
    6 links listed.
    
  4. 看来我需要从头来,首先要真正理解我配置的是什么?等吃完早饭再说吧!再复习一下概念
    Though both are for tunneling purposes, TUN and TAP can't be used together because they transmit and receive packets at different layers of the network stack. TUN, namely network TUNnel, simulates a network layer device and operates in layer 3 carrying IP packets. TAP, namely network TAP, simulates a link layer device and operates in layer 2 carrying Ethernet frames. TUN is used with routing. TAP can be used to create a user space network bridge.
    两者相似但是功能是有些许差别吧?这个概念我刚刚学完就忘了因为根本就没有真正的领悟。因为它们具体是怎么实操的离开了实践空谈什么层级都是无用的。
  5. 关于一个小问题/dev/net的权限,默认就是可以的:
    
    $ ll -d /dev/net
    drwxr-xr-x 2 root root 60 Apr 19 15:01 /dev/net/
    
    也就是说默认sudo chmod 0755 /dev/net应该是足够的,因为连它下面的设备文件都是用户可读写的,因为本来内核就是设计这个tun设备是一个用户可以自由创建的设备。这里我有一个非常幼稚的问题,就是为什么目录需要的权利?我以前认为似乎执行的权利就够了,实在是老糊涂了。这个问题太初级了吧?可是我确实不知道!

    This is because the directory itself only contains filenames and inode numbers—that's all.

    Read access to the filenames is controlled by the read permission.

    Access to the inodes pointed to by the directory is controlled by the execute permission—not the read permission. The inodes contain all the actual details about the file, such as filesize, owner, permissions, time last modified, and the physical location (on your physical hard disk) of the binary data which comprises the file's contents.

    To view the names of the files in the directory—you need read permission on the directory. You don't need execute or write permissions for this.


四月二十七日 等待变化等待机会

  1. 有一个感人的视频,很多人全程泪目。
  2. 这个是以前找到的关于OVMF的官方指引。那么什么是EDK II呢?这个TianoCore,它和EDK II是紧密联系的。EDK II stands for Enhanced Build Environment。目前熟悉名词是我的最大的收获。
  3. 回过头来尽快解决TAP的问题,我决定深入研究这个指引
    1. 首先,TAP是什么?它是内核的一个feature能够创建虚拟网卡表现的好像真的网卡,但实际上包是送到一个用户级程序。我感觉我还是在英译中的学习。但是这个确实是概念理解的第一步,每个字都是很重要的理解。这个和我在TAP/TUN的主页学习的概念是相一致的。当初内核驱动的设计思想也是这样子的,/dev/net/tun是枢纽而它是用户可读写的,这个是从内核就开放的用户级别访问的。
      Tap devices are a Linux kernel feature that allows you to create virtual network interfaces that appear as real network interfaces. Packets sent to a tap interface are delivered to a userspace program, such as QEMU, that has bound itself to the interface.
    2. 这个是之前就明白的,TAP是以太网的级别的模拟,但是具体的机制和IP层级区别在哪里呢?我的概念依然模糊。
      QEMU can use tap networking for a virtual machine so that packets sent to the tap interface will be sent to the virtual machine and appear as coming from a network interface (usually an Ethernet interface) in the virtual machine. Conversely, everything that the virtual machine sends through its network interface will appear on the tap interface.
    3. Tap devices are supported by the Linux bridge drivers, so it is possible to bridge together tap devices with each other and possibly with other host interfaces such as eth0. This is desirable if you want your virtual machines to be able to talk to each other, or if you want other machines on your LAN to be able to talk to the virtual machines.
      TAP是被bridge支持的,并不是说它本身就是桥实现的,这个目的显然是方便在不同网段的主机,不管是虚拟机还是物理机互相通讯。这个我开始有些概念了。
    4. 这里提到另一个选项host only networking,我打算下一步再去研读。
    5. 但是我之前已经尝试过这个方式有什么前提没有设置吧?
      
      qemu-system-x86_64 -kernel tmp/vmlinuz-5.15.0-25-generic  -serial stdio -m 2G  -drive format=raw,file=ubuntu-efi-disk -append "root=PARTUUID=8613E0D8-6556-7A47-922D-EDA26D53D20B console=ttyS0 earlyprintk=ttyS0" -netdev tap,ifname=tap0,id=network0,br=virtbr0,script=no,downscript=no -device virtio-net,netdev=network0
      
    6. 前进之前需要先后退半步,我打算再次理解user-mode的实质,这个也许能够比较而理解为什么我遗漏了什么?
      By default, without any -netdev arguments, QEMU will use user-mode networking with a built-in DHCP server. Your virtual machines will be assigned an IP address when they run their DHCP client, and they will be able to access the physical host's network through IP masquerading done by QEMU.
      这里的要点依然是两方面的,首先是qemu使用内部的DHCP server为你的虚拟机分配网址,但是另一方面是虚拟机需要自己主动使用DHCP client开机就寻找服务,这个听上去似乎是默认的,但是世界上没有配置是没有默认的。对于一个从头创建的操作系统任何配置都是需要自己去做的。所以,这里才引出了开机服务的问题。这一点我以前是模糊的,因为到底是哪一个服务呢?ubuntu很久以前就专向了systemd,我似乎从那以后就不明白Networking-Manager的角色到底是什么,至今我对于谁是主角依然是模糊的认识。
    7. 似乎是回应我的一些疑惑,这里提到的IPV6下的ping不工作似乎正是为什么虚拟机可以正常ping谷歌的原因,
      Note: ICMPv6 will not work, as support for it is not implemented: Slirp: external icmpv6 not supported yet. Pinging an IPv6 address will not work.
      因为我的观察是我的openvpn似乎对于配置IPv6有问题,反而我在主机需要ping -4 www.google.com才能工作,而在虚拟机则似乎天然不需要参数-4,也许是因为它天然就禁止了ipv6所以,默认就是ipv4。这个是一个额外的信息。
    8. user-mode的能力极限和特点是什么呢?
      QEMU's user-mode networking can offer more capabilities such as built-in TFTP or SMB servers, redirecting host ports to the guest (for example to allow SSH connections to the guest) or attaching guests to VLANs so that they can talk to each other. See the QEMU documentation on the -net user flag for more details.
      所以,这几样是我将来可以尝试的部分。
      
      -netdev user,id=str[,ipv4=on|off][,net=addr[/mask]][,host=addr]
               [,ipv6=on|off][,ipv6-net=addr[/int]][,ipv6-host=addr]
               [,restrict=on|off][,hostname=host][,dhcpstart=addr]
               [,dns=addr][,ipv6-dns=addr][,dnssearch=domain][,domainname=domain]
               [,tftp=dir][,tftp-server-name=name][,bootfile=f][,hostfwd=rule][,guestfwd=rule][,smb=dir[,smbserver=addr]]
                      configure a user mode network backend with ID 'str',
                      its DHCP server and optional services
      
      这个是目前user-mode的所有选项吗?
    9. 所以,这里是我需要了解的user-mode的虚拟机方面的部分,就是如果使用systemd-networkd的基本配置和要求: 首先是如何排除其他的服务的干扰?这一点我其实很模糊,因为systemctl --type=service到底还有那些network相关的服务,我居然没有很清楚的概念。其次是通过查看networkd可以看到它启动的一些细节: --no-pager --full可以看到全部的log细节。
      
      ~# systemctl --no-pager --full status systemd-networkd
      ● systemd-networkd.service - Network Configuration
           Loaded: loaded (/lib/systemd/system/systemd-networkd.service; enabled; vendor preset: enabled)
           Active: active (running) since Sat 2024-04-27 08:45:10 CST; 9min ago
      TriggeredBy: ● systemd-networkd.socket
             Docs: man:systemd-networkd.service(8)
         Main PID: 170 (systemd-network)
           Status: "Processing requests..."
            Tasks: 1 (limit: 2363)
           Memory: 2.7M
              CPU: 439ms
           CGroup: /system.slice/systemd-networkd.service
                   └─170 /lib/systemd/systemd-networkd
      
      Apr 27 08:45:09 nick-qemu systemd[1]: Starting Network Configuration...
      Apr 27 08:45:10 nick-qemu systemd-networkd[170]: lo: Link UP
      Apr 27 08:45:10 nick-qemu systemd-networkd[170]: lo: Gained carrier
      Apr 27 08:45:10 nick-qemu systemd-networkd[170]: Enumeration completed
      Apr 27 08:45:10 nick-qemu systemd[1]: Started Network Configuration.
      Apr 27 08:45:19 nick-qemu systemd-networkd[170]: eth0: Interface name change detected, renamed to ens3.
      Apr 27 08:45:19 nick-qemu systemd-networkd[170]: ens3: Link UP
      Apr 27 08:45:19 nick-qemu systemd-networkd[170]: ens3: Gained carrier
      Apr 27 08:45:20 nick-qemu systemd-networkd[170]: ens3: DHCPv4 address 10.0.2.15/24 via 10.0.2.2
      Apr 27 08:45:21 nick-qemu systemd-networkd[170]: ens3: Gained IPv6LL
      
      总而言之,user-mode是通过qemu的DHCP server来获得一个外界不可见的内网ip来访问外网。那么所谓的外网不可见是真的吗?这个应该是qemu的控制吧?10.0.2.2是默认网关它不放行你是无法访问的吧?
    10. networkd和resolved两者是既独立又关联的关系。后者是DNS相关服务的。
      systemd-resolved is a systemd service that provides network name resolution to local applications via a D-Bus interface, the resolve NSS service (nss-resolve(8)), and a local DNS stub listener on 127.0.0.53.
      这短短一句话包含了多少的信息啊!我之前为了openvpn的DNS解析看了非常多相关的资料,但是至今也还是模模糊糊的。总之,它是域名解析,但是它的接口居然是有三个不同的来源,首先是D-bus,因为最早通过C-style的library是古老的,大概就是get-host-name之类的吧?我又忘了错了!这两个函数我总是搞混,不知道为什么!是glibc's getaddrinfo(3),而这个NSS我至今依然不明白是怎么回事,似乎都是历史遗留问题,至于127.0.0.53则是一个人人都可以访问的古老的来源,因为很多基于权限因素它们喜欢使用这个方式来侦听。这个领域看似简单但是错综复杂。
    11. 单单看看这个定义就知道这里面学问其实很大:
      systemd-resolved provides resolver services for Domain Name System (DNS) (including DNSSEC and DNS over TLS), Multicast DNS (mDNS) and Link-Local Multicast Name Resolution (LLMNR)
      对于不熟悉网络的我来说,这里每一个都是深渊,域名解析本身也是一个危险的领域,因为有安全问题,黑客绑架这个等于从源头垄断了你的访问,而很多政府防火墙的机制就是从这里来的。至于后者我都没有听说过。
    12. 对!有四种模式!天啊!
      To provide domain name resolution for software that reads /etc/resolv.conf directly, such as web browsers, Go and GnuPG, systemd-resolved has four different modes for handling the file—stub, static, uplink and foreign.
      这里引出了更多的疑问,为什么Go程序和什么GnuPG要单独拿出来说事呢? 浏览器是直接读这个/etc/resolv.conf的,这个我可以理解,但是另外两个是什么鬼?
      
      ~# cat /etc/resolv.conf 
      # This is /run/systemd/resolve/stub-resolv.conf managed by man:systemd-resolved(8).
      # Do not edit.
      #
      # This file might be symlinked as /etc/resolv.conf. If you're looking at
      # /etc/resolv.conf and seeing this text, you have followed the symlink.
      #
      # This is a dynamic resolv.conf file for connecting local clients to the
      # internal DNS stub resolver of systemd-resolved. This file lists all
      # configured search domains.
      #
      # Run "resolvectl status" to see details about the uplink DNS servers
      # currently in use.
      #
      # Third party programs should typically not access this file directly, but only
      # through the symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a
      # different way, replace this symlink by a static file or a different symlink.
      #
      # See man:systemd-resolved.service(8) for details about the supported modes of
      # operation for /etc/resolv.conf.
      
      nameserver 127.0.0.53
      options edns0 trust-ad
      search .
      
      首先,这里的确是一个软链接
      
      ~# ll /etc/resolv.conf 
      lrwxrwxrwx 1 root root 39 Apr 13 12:01 /etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf
      
      其次,internal DNS stub resolver到底指的是什么?到底这里说的是127.0.0.53吗?
      
      ~# resolvectl status
      Global
             Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
      resolv.conf mode: stub
      
      Link 2 (ens3)
          Current Scopes: DNS
               Protocols: +DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
      Current DNS Server: 10.0.2.3
             DNS Servers: 10.0.2.3
      
      所以,支持这三种不同的协议-LLMNR -mDNS -DNSOverTLS,我的虚拟网卡额外的这个DefaultRoute是什么协议?我原来以为默认的DNS的ip是10.0.2.2,为什么这里是10.0.2.3又搞错了,10.0.2.2是DHCP server的ip,而DNS server的ip才是10.0.2.3
  4. 感觉好累啊!先吃早饭吧?
  5. 千呼万唤始出来,美国对于乌克兰开启了大规模军援模式,本来乌克兰是美国在围棋盘上一块打入的孤子没打算一定能够做活,可谓是一个轻投入试应手的没有包袱的棋子,随时可以放弃,是很轻的资产。但是随着乌克兰透露出可以一战的能力以及前期的大投入,这个棋子越走越重,现在已经走成了快要既决胜负也决生死的关键地区了。这个是美国始终都在避免而又不知不觉的滑入的深渊。面对着美国目前的广泛利用盟友的做法其实是有利有弊的,一战二战给德国的教训就是差劲的盟友比没有盟友可能更糟糕!因为你在借重盟友的力量的同时也是被你的盟友借重的过程,最终的妥协与调和不知道会把既定方向导向何方。

Smiley face