0. 引言

为了让每个人都可以把自己练入 LLM, 制作自己的数字分身. 解析 QQ 数据库无疑是快速获得语料库的最佳途径. 然而, 众所周知, QQ 的数据库是加密的 SQLite 数据库, 且不幸的是, 在最新的 NTQQ 中数据库的加密方式已经发生了变化. 本文将介绍如何解析 Mac 的 NTQQ 数据库.

参考资料 (win): Young-Lord/qq-win-db-key

该方案于 2023 年 9 月 19 日在 NTQQ 6.9.17 上测试通过. 严禁用于非法用途.

1. 准备工作

在开始解析之前, 我们需要准备一些工具:

因为我们的流程非常简单, 免费版的 Hopper 即可满足需求.

2. 分析

你需要先准备一个自己喜欢的工作目录, 并且将 NTQQ 的 Library 复制到当前目录下:

1
cp /Applications/QQ.app/Contents/Resources/app/wrapper.node .

随后, 你需要使用 Hopper 打开 wrapper.node 在 Mac M1/M2 上需要选择 aarch64, 并且搜索 nt_sqlite3_key_v2.

Search References to References to

如上图所示, 我们可以跳转到引用该函数的地方, 随后记下该函数地址:

Address

3. 断点 & 调试

随后我们运行 NTQQ, 找到它的进程 ID, 并且使用 LLDB 进行调试:

1
2
❯ ps aux | grep QQ
user 78488 1.5 0.5 1584651520 162000 ?? S 1:59PM 0:00.61 /Applications/QQ.app/Contents/MacOS/QQ
1
lldb -p 78488

我们需要寻找 wrapper.node 的加载地址:

1
2
(lldb) image list -o -f | grep /Applications/QQ.app/Contents/Resources/app/wrapper.node
[ 0] 0x0000000110088000 /Applications/QQ.app/Contents/Resources/app/wrapper.node

接下来进行一个简单的数学运算, 计算出 nt_sqlite3_key_v2 的地址:

1
2
(lldb) expr 0x0000000110088000 + 0x000000000192bef8
(unsigned long) $0 = 4590354168

设置断点并且继续运行:

1
2
3
4
5
(lldb) br s -a 4590354168
Breakpoint 1: where = wrapper.node`___lldb_unnamed_symbol287604, address = 0x00000001119b3ef8

(lldb) c
Process 78488 resuming

点击登录后, 如无意外, 你会看到断点被命中, 并且进入了 nt_sqlite3_key_v2 函数, 如下图所示:

breakpoint

参考函数签名:

1
2
3
4
5
int sqlite3_key_v2(
sqlite3 *db, /* Database to be keyed, x0 */
const char *zDbName, /* Name of the database, x1 */
const void *pKey, int nKey /* The key, x2, x3 */
);

接下来解析 16 个字符即可:

1
2
3
4
5
(lldb) register read x2
x2 = 0x0000012801b34010

(lldb) memory read --format c --count 16 --size 1 0x0000012801b34010
0x12801b34010: L7LA=idk17,fn~uk

至此, 我们已经成功解析出了 NTQQ 的数据库密钥.

4. 解密

数据库位于 (注意 MD5 可能会随着 QQ 的版本更新而改变):

1
/Users/user/Library/Containers/com.tencent.qq/Data/Library/Application Support/QQ/nt_qq_{MD5}/nt_db

复制你需要的文件, 如 profile_info.db, 跳过前 1024 个字节:

1
2
3
cp "/Users/user/Library/Containers/com.tencent.qq/Data/Library/Application Support/QQ/nt_qq_cc067b8bcbf8980fabd93574e09d9efa/nt_db/profile_info.db" test.db
cat test.db | tail -c +1025 > test.clean.db
rm test.db

随后, 打开 DB Browser for SQLite, 选择 test.clean.db, 输入密钥和 KDF = 4000, 即可成功解密:

DB Browser for SQLite DB Browser for SQLite

出于隐私考虑, 不展示解密后的数据库内容.

5. 总结

本文介绍了如何解析 NTQQ 的数据库, 以及如何使用 DB Browser for SQLite 浏览数据库.
需要注意的是, 数据库结构仍需分析, 本文仅仅是提供了解密的方法.

再次感谢 Young-Lord/qq-win-db-key 提供的思路.
再次声明, 本文仅用于学习交流, 严禁用于非法用途.

论文原文: Upsampling artifacts in neural audio synthesis

导言

在实践声码器时,我们常选择使用生成对抗网络(GAN)或自回归模型。由于自回归模型生成过程较慢,我们更倾向于使用GAN。目前,大部分广泛应用的GAN都源于HiFiGAN的改进,然而,无论是HiFiGAN还是其改进版,都存在上采样瑕疵的问题,如下图:

Viz

尽管本文未能找到完美的解决方案,但更充足的训练和SubPixel CNN能够减轻这类瑕疵。(不过,SubPixel Convolution会引入新的瑕疵。)

HiFiGAN

HiFiGAN的问题在于使用了Transposed Convolution(转置卷积)进行上采样,而这种方法会带来一些瑕疵。众所周知,转置卷积会导致Checkerboard瑕疵,这是因为其输出存在重叠部分。在HiFiGAN的默认配置中,我们的卷积核大小是步长的两倍。根据相关论文,这被称为Full Overlap,如下图:

Overlap Transposed Conv Artifact

经过多次上采样后,这种瑕疵在生成的样本中以明显的横线出现。

其他尝试

作者在此基础上,尝试了不同的上采样方案,包括:

  • 最近邻插值
  • 线性插值
  • 转置卷积
  • SubPixel卷积
Table

结果显示,转置卷积和SubPixel卷积的效果相当,且在客观评价指标上优于其他方案。然而,基于插值的方案在主观听感上与另外两种方案相差不大。

总结

转置卷积依然是目前最优的解决方案,它被广泛应用在众多模型中,并且其速度远超插值。幸运的是,通过增加网络层数和充足的训练(例如:Demucs),这类瑕疵可以被大幅降低。

在附录中,作者提到在STFT中使用center=False可以避免产生和混合Boundary瑕疵。

避免上采样的方案

基于频谱的生成方案如Vocos和iSTFT Net可以避免上采样瑕疵,但它们也会引入一些新的瑕疵,这一方向还需要进一步的研究。

参考文献

论文原文: Improving Multimodal Datasets with Image Captioning

选择 BLIP 2 的原因

BLIP 2

BLIP 2 的核心组件包括 Frozen Image Encoder、Frozen LLM 以及 Q-Former。它在 Image Captioning 方面表现出了强大的性能,特别是在生成样本的 Diversity 方面,显著超过了 OpenCLIP-CoCa。因此,我们选择 BLIP 2 来提升多模态数据集的效能。

多模态数据集中的挑战

CLIP Score Diversity & Noise

我们常常面临的问题是数据集的规模只有 100-200M,远未达到 Billion 级别。在这种情况下,数据质量的重要性不言而喻。然而,像 DataComp 128M 这样的数据集的 CLIP Score 平均只有 0.2,其中存在大量与文字不相关的图片和噪声。一个直接的解决方法是过滤掉与文字不相关的图片,仅保留 top 30%,但这会导致数据集的规模大幅度缩减,且一定程度上降低了数据的 Diversity。

解决策略

作者在试验和数据分析后,选择了如下策略:

  1. 计算已有数据集的 CLIP Score,保留 top 30% 的图片。
  2. 对剩余的 70% 的图片使用 BLIP 2 生成 caption。
  3. 对生成的 Caption 进行过滤,过滤标准与 Step 1 相同。

这个策略实际上可以看作是对 BLIP 2 进行了一种形式的 knowledge distillation,使模型学习到了 ViT-G 和 BLIP2 数据集 LAION400M 的分布。实际上,当数据集的规模扩大到 400M 以上时,这种策略的效果几乎与直接保留原始数据的 Top 30% 相当。

Comparison

参考文献

以下框架均来源于个人 PyTorch 开发经历, 仅供参考. (以下内容不分先后)

  • Albumentations: 一个基于 OpenCV 的图像增强/解析库, 速度爆杀 torchvision (Pillow-SIMD).
  • Einops: 一个 PyTorch 的 Tensor 操作库, 可以在大幅简化 transpose, reshape, squeeze, unsqueeze 等操作.
  • PyTorch Lightning: 一个 PyTorch 的高级封装, 可以大幅简化训练过程的代码, 如 DDP, Logging, Checkpointing, 等等.
  • PyTorch Image Models: (TIMM): 一个耳熟能详的 CV 模型库.
  • HuggingFace Transformers: 一个耳熟能详的 NLP 模型库.
  • ONNX Runtime: 一个 ONNX 的运行时, 可以用来大幅加速 PyTorch 模型的推理, 支持 CPU, CUDA, CoreML, TensorRT 等后端.
  • WandB: 一个可视化工具 (类似 tensorboard), 可以用来记录训练过程中的各种指标, 以及可视化训练过程中的图片, 模型, 等等.

如果你有其他推荐, 欢迎在评论区留言.

很多时候我们需要使用 OpenCV 的一些功能 (如 viz), 但是 OpenCV 官方的 Python Contrib 版本并没有提供这些功能, 这时候我们就需要使用自己构建.
然而, 手动从官方下载源码然后构建相当繁琐, 下面的代码将使用 pip 来构建 OpenCV Contrib Python.

1
2
3
4
export ENABLE_CONTRIB=1  # 启用 contrib
export CMAKE_ARGS="-DWITH_VTK=ON -DOPENCV_ENABLE_NONFREE=ON" # 启用 VTK 和非免费功能
export MAKEFLAGS="-j$(nproc)" # 使用多核编译
pip install -v --no-binary=opencv-contrib-python opencv-contrib-python

在这里, 我使用 CMAKE_ARGS 来指定 CMAKE 参数, 你们可以根据自己的需求调整.

0%