完美解决wsl+docker的二级代理上网问题

继续上一篇,基于wsl2的docker-desktop创建fast-whisper无法正常运行,错误日志如下:

2023-07-06 17:10:29 Traceback (most recent call last):
2023-07-06 17:10:29   File "/usr/local/lib/python3.8/dist-packages/gradio/routes.py", line 394, in run_predict
2023-07-06 17:10:29     output = await app.get_blocks().process_api(
2023-07-06 17:10:29   File "/usr/local/lib/python3.8/dist-packages/gradio/blocks.py", line 1075, in process_api
2023-07-06 17:10:29     result = await self.call_function(
2023-07-06 17:10:29   File "/usr/local/lib/python3.8/dist-packages/gradio/blocks.py", line 884, in call_function
2023-07-06 17:10:29     prediction = await anyio.to_thread.run_sync(
2023-07-06 17:10:29   File "/usr/local/lib/python3.8/dist-packages/anyio/to_thread.py", line 31, in run_sync
2023-07-06 17:10:29     return await get_asynclib().run_sync_in_worker_thread(
2023-07-06 17:10:29   File "/usr/local/lib/python3.8/dist-packages/anyio/_backends/_asyncio.py", line 937, in run_sync_in_worker_thread
2023-07-06 17:10:29     return await future
2023-07-06 17:10:29   File "/usr/local/lib/python3.8/dist-packages/anyio/_backends/_asyncio.py", line 867, in run
2023-07-06 17:10:29     result = context.run(func, *args)
2023-07-06 17:10:29   File "app.py", line 103, in transcribe_webui_simple_progress
2023-07-06 17:10:29     return self.transcribe_webui(modelName, languageName, urlData, multipleFiles, microphoneData, task, vadOptions,
2023-07-06 17:10:29   File "app.py", line 197, in transcribe_webui
2023-07-06 17:10:29     result = self.transcribe_file(model, source.source_path, selectedLanguage, task, vadOptions, scaled_progress_listener, **decodeOptions)
2023-07-06 17:10:29   File "app.py", line 280, in transcribe_file
2023-07-06 17:10:29     process_gaps = self._create_silero_config(NonSpeechStrategy.CREATE_SEGMENT, vadOptions)
2023-07-06 17:10:29   File "app.py", line 368, in _create_silero_config
2023-07-06 17:10:29     self.vad_model = VadSileroTranscription()
2023-07-06 17:10:29   File "/opt/whisper-webui/src/vad.py", line 437, in __init__
2023-07-06 17:10:29     self._initialize_model()
2023-07-06 17:10:29   File "/opt/whisper-webui/src/vad.py", line 445, in _initialize_model
2023-07-06 17:10:29     self.model, self.get_speech_timestamps = self._create_model()
2023-07-06 17:10:29   File "/opt/whisper-webui/src/vad.py", line 449, in _create_model
2023-07-06 17:10:29     model, utils = torch.hub.load(repo_or_dir='snakers4/silero-vad', model='silero_vad')
2023-07-06 17:10:29   File "/usr/local/lib/python3.8/dist-packages/torch/hub.py", line 537, in load
2023-07-06 17:10:29     repo_or_dir = _get_cache_or_reload(repo_or_dir, force_reload, trust_repo, "load",
2023-07-06 17:10:29   File "/usr/local/lib/python3.8/dist-packages/torch/hub.py", line 180, in _get_cache_or_reload
2023-07-06 17:10:29     repo_owner, repo_name, ref = _parse_repo_info(github)
2023-07-06 17:10:29   File "/usr/local/lib/python3.8/dist-packages/torch/hub.py", line 133, in _parse_repo_info
2023-07-06 17:10:29     with urlopen(f"https://github.com/{repo_owner}/{repo_name}/tree/main/"):
2023-07-06 17:10:29   File "/usr/lib/python3.8/urllib/request.py", line 222, in urlopen
2023-07-06 17:10:29     return opener.open(url, data, timeout)
2023-07-06 17:10:29   File "/usr/lib/python3.8/urllib/request.py", line 525, in open
2023-07-06 17:10:29     response = self._open(req, data)
2023-07-06 17:10:29   File "/usr/lib/python3.8/urllib/request.py", line 542, in _open
2023-07-06 17:10:29     result = self._call_chain(self.handle_open, protocol, protocol +
2023-07-06 17:10:29   File "/usr/lib/python3.8/urllib/request.py", line 502, in _call_chain
2023-07-06 17:10:29     result = func(*args)
2023-07-06 17:10:29   File "/usr/lib/python3.8/urllib/request.py", line 1397, in https_open
2023-07-06 17:10:29     return self.do_open(http.client.HTTPSConnection, req,
2023-07-06 17:10:29   File "/usr/lib/python3.8/urllib/request.py", line 1357, in do_open
2023-07-06 17:10:29     raise URLError(err)
2023-07-06 17:10:29 urllib.error.URLError: <urlopen error [Errno 111] Connection refused>
2023-07-06 17:10:29 Traceback (most recent call last):
2023-07-06 17:10:29   File "/usr/lib/python3.8/urllib/request.py", line 1354, in do_open
2023-07-06 17:10:29     h.request(req.get_method(), req.selector, req.data, headers,
2023-07-06 17:10:29   File "/usr/lib/python3.8/http/client.py", line 1256, in request
2023-07-06 17:10:29     self._send_request(method, url, body, headers, encode_chunked)
2023-07-06 17:10:29   File "/usr/lib/python3.8/http/client.py", line 1302, in _send_request
2023-07-06 17:10:29     self.endheaders(body, encode_chunked=encode_chunked)
2023-07-06 17:10:29   File "/usr/lib/python3.8/http/client.py", line 1251, in endheaders
2023-07-06 17:10:29     self._send_output(message_body, encode_chunked=encode_chunked)
2023-07-06 17:10:29   File "/usr/lib/python3.8/http/client.py", line 1011, in _send_output
2023-07-06 17:10:29     self.send(msg)
2023-07-06 17:10:29   File "/usr/lib/python3.8/http/client.py", line 951, in send
2023-07-06 17:10:29     self.connect()
2023-07-06 17:10:29   File "/usr/lib/python3.8/http/client.py", line 1418, in connect
2023-07-06 17:10:29     super().connect()
2023-07-06 17:10:29   File "/usr/lib/python3.8/http/client.py", line 922, in connect
2023-07-06 17:10:29     self.sock = self._create_connection(
2023-07-06 17:10:29   File "/usr/lib/python3.8/socket.py", line 808, in create_connection
2023-07-06 17:10:29     raise err
2023-07-06 17:10:29   File "/usr/lib/python3.8/socket.py", line 796, in create_connection
2023-07-06 17:10:29     sock.connect(sa)
2023-07-06 17:10:29 ConnectionRefusedError: [Errno 111] Connection refused

很明显是github无法访问,我首先想到的是docker无法走系统的代理,wsl也不行,通过在docker和wsl中运行curl https://www.google.com可以测试。(fast-whisper镜像不像whiper那样把东西都放进去了,每次运行时还要加载东西,造成这个问题。也就是说whisper官方镜像可以全脱网运行,fast-whisper则不行。)

那么怎么让没有开通局域网共享功能的梯子来分享网络呢?通过一阵子检索,终于发现了二级代理和链式代理这个概念,最终确定用gost试一试。

1 在windows上找到当前的代理

打开网络连接的“网络和Internet设置”,打开设置中的“代理”。如果你安装了某个代理程序,则这里应该能够看到设置的端口。比如地址:http://localhost,端口:15236。

注意,这里的localhost很重要,因为收费的代理不希望你局域网共享,所以限制只能通过localhost访问。如果没有这个限制,那就简单了,直接把代理设置为主机的IP和端口就行了。

2 安装gost作为二级代理

由于我的梯子是在win10上的,所以需要让gost也在win上运行,所以安装了win版的go,然后安装/build这个gost,目录下就有gost.ext了,运行:

.\gost -L=:15230 -F=localhost:15236

二级代理就启动了,最直接的是在另外一台电脑上设置这个IP加端口15230试试,发现代理成功。试了一下,必须是localhost,不能是127.0.0.1。

为了方便,我把这个设置了自动启动,在gost.exe所在目录增加一个名为gost.ps1的文件,内容如下:

.\gost.exe -L=:16236 -F=localhost:15236

同样在这个目录再增加一个gost.bat,内容如下:

Powershell.exe -executionpolicy remotesigned -File ./gost.ps1

然后在gost.bat上右键创建一个快捷方式,把这个快捷方式放到开机启动目录C:\Users\PS\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup

可以通过徽标键+R打开shell:startup

3 在wsl中配置代理的启用

然后可以借鉴WSL2配置代理 – Leaos – 博客园 (cnblogs.com)来设置wsl2中的代理。

还有个问题,DNS也要先加上8.8.8.8,不然域名解析被污染了,依然无法访问github。

一个更方便的方法,在wsl的用户主目录增加一个文件proxy.sh,内容如下:

#!/bin/sh
# hostip=$(cat /etc/resolv.conf | grep nameserver | awk '{ print $2 }')
hostip='192.168.0.200'
wslip=$(hostname -I | awk '{print $1}')
port=16236
 
PROXY_HTTP="http://${hostip}:${port}"
PROXY_SOCKS5="socks5://${hostip}:${port}"
 
set_proxy(){
  export http_proxy="${PROXY_HTTP}"
  export HTTP_PROXY="${PROXY_HTTP}"
 
  export https_proxy="${PROXY_HTTP}"
  export HTTPS_proxy="${PROXY_HTTP}"
 
  export ALL_PROXY="${PROXY_SOCKS5}"
  export all_proxy="${PROXY_SOCKS5}"
 
  git config --global http.https://github.com.proxy ${PROXY_HTTP}
  git config --global https.https://github.com.proxy ${PROXY_HTTP}
 
  echo "Proxy has been opened."

  test_setting
}
 
unset_proxy(){
  unset http_proxy
  unset HTTP_PROXY
  unset https_proxy
  unset HTTPS_PROXY
  unset ALL_PROXY
  unset all_proxy
  git config --global --unset http.https://github.com.proxy
  git config --global --unset https.https://github.com.proxy
 
  echo "Proxy has been closed."
}
 
test_setting(){
  echo "Host IP:" ${hostip}
  echo "WSL IP:" ${wslip}
  echo "Current https_proxy:" $https_proxy
  echo "Current all_proxy:" $all_proxy
  echo "Try to connect to Google..."
  resp=$(curl -I -s --connect-timeout 5 -m 5 -w "%{http_code}" -o /dev/null www.google.com)
  if [ ${resp} = 200 ]; then
    echo "Proxy setup succeeded!"
  else
    echo "Proxy setup failed!"
  fi
}
 
if [ "$1" = "set" ]
then
  set_proxy
 
elif [ "$1" = "unset" ]
then
  unset_proxy
 
elif [ "$1" = "test" ]
then
  test_setting
else
  echo "Unsupported arguments."
fi

注意,其中的hostip我没有用其他文档给的方法,因为不确定一定对,我改成了本机的固定IP。

然后在.bashrc文件结尾增加

alias proxy="source ~/proxy.sh set"
alias unproxy="source ~/proxy.sh unset"

这样,在source ~/.bashrc之后,就可以直接在shell中输入proxy来启用,或者输入unproxy来停用了。

再进一步,想要在打开shell时自动配置,可以新建一个autoproxy.sh

#!/bin/sh
# hostip=$(cat /etc/resolv.conf | grep nameserver | awk '{ print $2 }')
hostip='192.168.0.200'
wslip=$(hostname -I | awk '{print $1}')
port=16236
 
PROXY_HTTP="http://${hostip}:${port}"
PROXY_SOCKS5="socks5://${hostip}:${port}"


export http_proxy="${PROXY_HTTP}"
export HTTP_PROXY="${PROXY_HTTP}"

export https_proxy="${PROXY_HTTP}"
export HTTPS_proxy="${PROXY_HTTP}"

export ALL_PROXY="${PROXY_SOCKS5}"
export all_proxy="${PROXY_SOCKS5}"

git config --global http.https://github.com.proxy ${PROXY_HTTP}
git config --global https.https://github.com.proxy ${PROXY_HTTP}

echo "Proxy has been opened."

然后在.bashrc中增加


if [ -f "/home/yourusername/autoproxy.sh" ]; then
    . "/home/yourusername/autoproxy.sh"
fi

win10部署fast-whisper实测最佳方案

因为不喜欢win10上的shell,一直都比较喜欢在wsl中的ubuntu中跑服务,结果轮到fast-whisper的时候发现容器中无法加载模型,因为无法利用宿主机的代理,又不太方便把模型下载完放进去。

还有个情况是,无法用到GPU,导致用CPU跑超慢。

win10上的docker-desktop也是基于wsl的,但是创建容器的时候发现有个区别,一种是在powershell中跑命令,那么创建的容器可以走代理,下载模型顺利,而在wsl中的ubuntu跑创建docker命令创建的容器则不行,目前没有资料证实是否这样,没有太多时间再去研究这个网络。

最后实测最佳方案是,在powershell中运行:

docker run -d --gpus all -p 7860:7860 --name fast-whisper --mount type=bind,source=$(pwd)/.cache/whisper,target=/root/.cache/whisper --mount type=bind,source=$(pwd)/.cache/huggingface,target=/root/.cache/huggingface --restart=on-failure:15 registry.gitlab.com/aadnk/whisper-webui:latest app.py --input_audio_max_duration -1 --server_name 0.0.0.0 --auto_parallel True --default_vad silero-vad --default_model_name large-v2

另外,打开Word Timestamps – Highlight Words以后,效果似乎更棒一些,还加上了标点符号,准确度很高。

本地化搭建fast-whisper+ChatGLM2-6B出来会谈记录

ffmpeg -i  20230703am.mp3 -f segment -segment_time 1755 -write_xing 0 -c copy  20230703am/out%03d.mp3

首先用以上命令将长音频切分为每30分钟一段,因为fast-whisper有这样的限制,实际切分的时候不要设置为1800秒,因为会多一点点,无法通过,可以设置到1799秒。

fast-whisper用官方的docker方案直接跑,试了一下medium模型和largv2都还行,默认就用medium了。

转录出来的文本用ChatGLM2-6B来处理,比如用这样的提示词:“请整理以下录音识别的文字,去掉其中的语气词等多余的部分,将语句调整通顺,修复可能因为语音识别产生的错误。”

ChatGLM2-6B直接按官方库的方法部署即可,通过webui访问。

如果希望自己对照查看文本,可以用VLC打开audio的visualizations效果即可显示字幕,也可以用subtitle编辑。

用VLC播放mp3的时候,默认看不到字幕,需要手动打开音频可视化。

图形默认是正方的,看着有点别扭,那么再调整一下视频比例。

更详细的情况欢迎联系我交流。

自动压缩当前文件夹及所有子文件夹的图片代码

#!/usr/bin/python
# -*- coding: UTF-8 -*-

'''
Author: be_loving@163.com 
Date: 2023-06-26 20:13:21
LastEditors: be_loving@163.com 
LastEditTime: 2023-06-26 21:28:50
Description: 

Copyright (c) 2023 Jiulu LTD, All Rights Reserved. 
'''
# pip install Pillow
import os
from PIL import Image
Image.MAX_IMAGE_PIXELS = None

for root, dirs, files in os.walk(".", topdown=False):
    for name in files:

        if name.endswith(".jpg") or name.endswith(".jpeg") or name.endswith(".png") or name.endswith(".tif"):
            img_path = os.path.join(root, name)
            print(img_path)
            if img_path.count('_144') > 1:
                os.remove(img_path)
            elif img_path.count('_144') == 0:
                new_img_path = os.path.join(
                    root, f"{name}_144.jpg")
                print(new_img_path)
                if not os.path.isfile(new_img_path):
                    try:
                        with Image.open(img_path) as img:
                            img.save(new_img_path, dpi=(144, 144))
                    except(OSError, NameError):
                        print('OSError,Path:', img_path)

    # for name in dirs:
    #     print(os.path.join(root, name))

具体压缩参数及文件命名方式请自己参照pillow的文档修改。

脚本运行时可执行

python ./resize.py

但需要当前的python环境支持pillow,可以直接安装,也可以用conda来定制环境,比如在conda create命令下安装pillow之后用conda activate pillow激活该环境。

萤石云录像机CS-N1-208硬盘报警消除

萤石云录像机CS-N1-208突然间开始连续发出滴滴滴三声蜂鸣,打客服电话问,说可以把报警声关掉。

但检查后发现不只是有报警音的问题,关键是硬盘不转,以为硬盘坏了,换了一个硬盘,依然不转,进入系统,识别不到硬盘。以为主板坏了,打算换一个主板,结果在淘宝上了咨询了一下老板,直接回复是电源的问题,原来的使用的电源是0.7A(12V),远远不够,建议升到2A以上。

于是用一个笔记本电脑的电源(19V)加上一个可调降压模块(12V),开机成功,硬盘也恢复了。

我不理解的是之前它是怎么正常工作的。

顺带备注一下:这个录像机恢复初始密码后,密码是盒子标签上的验证码,区分大小写。网上查到的文档都是说12345,不对。

在ox11以上版本的mac上安装DocuPrint C1110B

DocuPrint C1110B大概是针对中国大陆市场投放的一个打印机型号,目前官方网站已经停止了对这个型号的售后支持,包括驱动下载,即使各种搜索,也只能在非官方网站上找到兼容到ox10的驱动安装包。

一直找到很晚,因为眼睛看花了,误把DocuPrint C1100看成了DocuPrint C1110,所以将错就错在下面这个网址下载了DocuPrint C1100的驱动。

https://www.fujifilm.com/fb/download/eng/docuprint

打开上面的网址,选择相应的型号,点击该型号链接,打开新的页面,切换到mac的tab上,选择想要的系统版本项,打开的是一个日文的页面,没关系,用一下翻译插件,点击同意并下载,在mac上打开这个驱动并安装。

在usb上连接上打印机,并开机,添加打印机,这个时候如果还是没有显示打印机型号,显示为普通的PLC打印机,则选择其他,然后定位到系统盘的“资源库-Printers-PPDS-Contents-Resources-FX DocuPrint C1100”即可添加成功。

第二天再仔细看才发现具体型号是DocuPrint C1100,到官网查看了一下产品照片,其实和DocuPrint C1110一样,那么用的芯片实际上也是一样的了。在武汉的时候修打印机的师傅告诉我,打印机虽然那么多型号,但实际上芯片规格并不多,很多很神奇的联想方正打印机,直接到日本打印机官网去下载某型号的驱动就可以用,因为都是贴牌或套壳的。

北京真露营时间区间

所谓真露营,就是真的在户外的露营地过夜,这两年很多说露营的实际上多半是野餐级别的。

那么对于多数人来说目前挑战高级别露营是有难度的,装备很贵,经验太少。那么,就在真露营里面,挑一个相对舒适的时间。

北京露营适宜区间(全年温度曲线图)

从图上来看,我们把轻度露营再分为两个级别,一个是夜间最低温度10度以上,一个是夜间最低温度15度以上。10度以上是从4月中旬到9月底,这5个多月的时间段,15度以上是从5月初到8月底这4个月的时间端。

关于露营期间玩什么,除了吃喝,还可以看电影、唱歌、打扑克。也可以看看书,听听音乐,看看星星。

vite项目引入vue3-carousel-3d时添加declare module ‘vue3-carousel-3d’

vite/vue3中引入vue3-carousel-3d组件时会报错,vue3-carousel-3d是基于vue-carousel-3d改造的,但没有提供types文件。为了解决这个问题,需要在项目中自行添加一个文件,比如命名为vendor.d.ts(可以放在types文件夹,并在tsconfig.json的types数组中添加./types/vendor.d.ts),内容如下:

declare module 'vue3-carousel-3d';

这样,就能正常使用了。