Static Local Linearization for Differentiable Discrete Programming
Project description
🎯 项目简介
SLL-Core 是一个基于 静态局部线性化(Static Local Linearization) 原理的 PyTorch 库,为离散操作提供零侵入式的自动微分能力。
核心优势:
- ✅ 零代码改动:直接装饰现有代码,无需修改模型结构
- ✅ 部署零开销:训练时可微,部署时自动恢复硬逻辑
- ✅ 稳定收敛:常数梯度设计,无梯度消失/爆炸问题
- ✅ 数学保证:当 ε→0 时,最优解收敛到原始离散问题
⚡ 快速开始
import torch
import sll_core
@ sll_core.linearize(eps=1e-2)
def my_discrete_function(x):
y = torch.sign(x)
z = torch.round(y * 10)
return z.sum()
x = torch.tensor([-1.0, 0.0, 1.0], requires_grad=True)
loss = my_discrete_function(x)
loss.backward()
print(x.grad)
🚀 安装
pip install sll-core
要求: Python ≥ 3.8,PyTorch ≥ 1.9.0
📖 使用方式
方式一:装饰器(推荐)
import torch
import sll_core
@ sll_core.linearize(eps=1e-3)
def custom_algorithm(x):
mask = (x > 0.5).float()
y = torch.sign(x)
return mask * y
x = torch.tensor([-0.5, 0.5], requires_grad=True)
y = custom_algorithm(x)
y.sum().backward()
方式二:上下文管理器
import torch
import sll_core
x = torch.tensor([1.2, 2.5], requires_grad=True)
with sll_core.linearize(eps=1e-3):
y = torch.round(x)
y.backward(torch.ones_like(y))
print(x.grad)
方式三:手动算子
from sll_core.ops import heaviside, sign, round, floor, ceil
x = torch.tensor([0.0], requires_grad=True)
y = sll_core.sign(x, eps=1e-3)
y.backward()
print(x.grad) # tensor([500.])
🔧 支持的算子
| 算子 | 描述 | 使用示例 |
|---|---|---|
heaviside |
Heaviside 阶跃函数 | sll_core.heaviside(x) |
sign |
符号函数 | sll_core.sign(x) |
round |
四舍五入 | sll_core.round(x) |
floor |
向下取整 | sll_core.floor(x) |
ceil |
向上取整 | sll_core.ceil(x) |
threshold |
通用阈值函数 | sll_core.threshold(x, threshold=0.5) |
🔬 应用场景
场景 1:量化感知训练 (QAT)
@ sll_core.linearize(eps=1e-3)
def quantize(x, levels=256):
scale = (levels - 1) / (x.max() - x.min() + 1e-10)
return torch.round((x - x.min()) * scale) / scale + x.min()
场景 2:组合优化
@ sll_core.linearize(eps=1e-2)
def knapsack(probabilities):
selected = (probabilities > 0.5).float()
total_weight = (selected * weights).sum()
total_value = (selected * values).sum()
penalty = torch.max(torch.tensor(0.0), total_weight - capacity) * 100
return total_value - penalty
场景 3:离散控制策略
@ sll_core.linearize(eps=1e-3)
def discrete_controller(state):
action_prob = torch.sigmoid(state)
action = (action_prob > 0.5).float() # 离散决策
return action
场景 4:神经网络剪枝
@ sll_core.linearize(eps=1e-3)
def magnitude_pruning(weights, threshold=0.01):
mask = (torch.abs(weights) > threshold).float()
pruned_weights = weights * mask
return pruned_weights
场景 5:图像分割阈值处理
@ sll_core.linearize(eps=1e-3)
def binary_segmentation(logits, threshold=0.5):
prob = torch.sigmoid(logits)
mask = (prob > threshold).float()
return mask
场景 6:强化学习动作选择
@ sll_core.linearize(eps=1e-2)
def epsilon_greedy_action(q_values, epsilon=0.1):
best_action = torch.argmax(q_values, dim=-1)
random_action = torch.randint(0, q_values.shape[-1], best_action.shape)
use_random = (torch.rand_like(best_action.float()) < epsilon).float()
action = (1 - use_random) * best_action.float() + use_random * random_action.float()
return action.long()
场景 7:数据压缩量化
@ sll_core.linearize(eps=1e-4)
def ternary_quantization(x):
scale = torch.max(torch.abs(x))
normalized = x / (scale + 1e-10)
quantized = torch.sign(normalized) * (torch.abs(normalized) > 0.5).float()
return quantized * scale
场景 8:稀疏注意力机制
@ sll_core.linearize(eps=1e-3)
def sparse_attention(attention_scores, top_k=16):
top_vals, top_idx = torch.topk(attention_scores, top_k, dim=-1)
mask = torch.zeros_like(attention_scores)
mask.scatter_(-1, top_idx, 1.0)
sparse_scores = attention_scores * mask
return sparse_scores / (sparse_scores.sum(dim=-1, keepdim=True) + 1e-10)
注意:Sll-Core可应用在几乎所有离散操作是"少量、局部"的,整体框架还是基于梯度下降的代码里。
⚙️ 参数说明
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
eps |
float | 1e-3 | 线性化区间半宽 |
eps 参数的作用:
- 输入距离硬边界 ≤ eps:使用线性化近似(有梯度)
- 输入距离硬边界 > eps:使用原始硬逻辑(梯度为0)
- eps 越小:越接近硬逻辑,梯度区域越窄
- eps 越大:过渡越平滑,近似区域越宽
📊 梯度对比
| 方法 | 前向输出 | 边界梯度 | 远离边界梯度 | 调参难度 |
|---|---|---|---|---|
| 硬函数 | 精确 | 0 | 0 | - |
| STE | 精确 | 1 | 1 | - |
| Sigmoid 松弛 | 有误差 | 高斯峰 | 0 | 高 |
| SLL | 精确 | 1/(2ε) | 0 | 低 |
💥 Demo:QAT 量化感知训练
🚀 零侵入式可微量化训练
import torch
import torch.nn as nn
import sll_core
class SimpleNet(nn.Module):
def __init__(self):
super().__init__()
self.fc1 = nn.Linear(10, 64)
self.fc2 = nn.Linear(64, 32)
self.fc3 = nn.Linear(32, 10)
@sll_core.linearize(eps=1e-3)
def quantize(self, x, levels=256):
scale = (levels - 1) / (x.max() - x.min() + 1e-10)
quantized = torch.round((x - x.min()) * scale) / scale + x.min()
return quantized
def forward(self, x):
x = self.fc1(x)
x = torch.relu(x)
x = self.quantize(x)
x = self.fc2(x)
x = torch.relu(x)
x = self.quantize(x)
x = self.fc3(x)
return x
model = SimpleNet()
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
criterion = nn.CrossEntropyLoss()
for epoch in range(100):
x = torch.randn(32, 10)
y = torch.randint(0, 10, (32,))
optimizer.zero_grad()
output = model(x)
loss = criterion(output, y)
loss.backward()
optimizer.step()
if (epoch + 1) % 20 == 0:
print(f"Epoch {epoch+1}, Loss: {loss.item():.4f}")
📊 对比实验:SLL vs STE vs Sigmoid 松弛
| 指标 | STE | Sigmoid 松弛 | SLL |
|---|---|---|---|
| 前向精度 | 精确 | 有误差 | 精确 |
| 收敛速度 | 慢 | 中等 | 最快 |
| 梯度消失 | 常见 | 偶发 | 无 |
| 调参难度 | - | 高 | 低 |
| 训练稳定性 | 差 | 中等 | 优秀 |
⚡ 性能数据
在 MNIST 量化感知训练任务上:
- SLL: 准确率 97.8%,训练 50 epoch 收敛
- STE: 准确率 94.2%,训练 100 epoch 未完全收敛
- Sigmoid: 准确率 95.1%,需精心调参
📈 训练损失对比(Demo训练损失)
🎯 核心优势展示
import torch
import sll_core
x = torch.tensor([0.001, 0.5, 0.999], requires_grad=True)
with torch.no_grad():
y_ste = torch.round(x)
y_ste.backward(torch.ones_like(y_ste), retain_graph=True)
print("STE 梯度:", x.grad) # tensor([1., 1., 1.])
x.grad.zero_()
@sll_core.linearize(eps=0.1)
def sll_round(x):
return torch.round(x)
y_sll = sll_round(x)
y_sll.backward(torch.ones_like(y_sll))
print("SLL 梯度:", x.grad) # tensor([0., 5., 0.])
结论:SLL 在保持前向精度的同时,智能地将梯度集中在真正需要优化的边界区域,实现更高效的训练。
🎨 梯度分布对比
实际测试结果:
- SLL 梯度:
[25.0, 0.0, 25.0, 0.0, 25.0]— 仅在边界处有梯度 - STE 梯度:
[1.0, 1.0, 1.0, 1.0, 1.0]— 处处有梯度,效率低下
🏛️ 项目结构
sll-core/
├── sll_core/
│ ├── __init__.py # 模块导出
│ ├── core.py # 核心 API(linearize)
│ ├── discovery.py # 自动发现装饰器
│ └── ops.py # SLL 算子实现
├── README.md
├── README_EN.md
├── LICENSE
└── pyproject.toml
📄 许可证
MIT License - 详见 LICENSE
🤝 贡献指南
欢迎提交 Issue 和 Pull Request!
开发环境
git clone https://github.com/jacksong-sourse/sll-core.git
cd sll-core
pip install -e .[dev]
运行测试
pytest tests/ -v
📚 引用
如果您在研究中使用 SLL,请引用:
@software{sll-core,
title = {SLL-Core: Static Local Linearization for Differentiable Discrete Programming},
author = {Jacksong},
year = {2026},
url = {https://github.com/jacksong-sourse/sll-core},
}
⭐ 如果这个项目对您有帮助,请给个 Star!
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sll_core-1.1.6.tar.gz.
File metadata
- Download URL: sll_core-1.1.6.tar.gz
- Upload date:
- Size: 15.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3beae238d2f1620942f1007211de7095a9d46fc4715839a56896019f210d1c33
|
|
| MD5 |
8e03308f5885dba82f5e202f8ea5f796
|
|
| BLAKE2b-256 |
5eb3b215ad1e40825a34f5cdd5a1cc7b85eea65b24f59f409a3469985ca5c9a4
|
Provenance
The following attestation bundles were made for sll_core-1.1.6.tar.gz:
Publisher:
publish.yml on jacksong-sourse/sll-core
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sll_core-1.1.6.tar.gz -
Subject digest:
3beae238d2f1620942f1007211de7095a9d46fc4715839a56896019f210d1c33 - Sigstore transparency entry: 1500403657
- Sigstore integration time:
-
Permalink:
jacksong-sourse/sll-core@3e6c40e0cd201efaafb9275cab2f028875938be2 -
Branch / Tag:
refs/tags/v1.1.6 - Owner: https://github.com/jacksong-sourse
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3e6c40e0cd201efaafb9275cab2f028875938be2 -
Trigger Event:
push
-
Statement type:
File details
Details for the file sll_core-1.1.6-py3-none-any.whl.
File metadata
- Download URL: sll_core-1.1.6-py3-none-any.whl
- Upload date:
- Size: 12.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d031fcd49ca5700b134b6bfec02097a84dc3a910b4e9824ed5daba30c9cddb4c
|
|
| MD5 |
b5440e9654048a6def27108f3ea6351b
|
|
| BLAKE2b-256 |
dd3fe02f38878d7af6d06507ed6bfeb77af5aacddf9dd54a9adb2e24b52797a9
|
Provenance
The following attestation bundles were made for sll_core-1.1.6-py3-none-any.whl:
Publisher:
publish.yml on jacksong-sourse/sll-core
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sll_core-1.1.6-py3-none-any.whl -
Subject digest:
d031fcd49ca5700b134b6bfec02097a84dc3a910b4e9824ed5daba30c9cddb4c - Sigstore transparency entry: 1500403763
- Sigstore integration time:
-
Permalink:
jacksong-sourse/sll-core@3e6c40e0cd201efaafb9275cab2f028875938be2 -
Branch / Tag:
refs/tags/v1.1.6 - Owner: https://github.com/jacksong-sourse
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3e6c40e0cd201efaafb9275cab2f028875938be2 -
Trigger Event:
push
-
Statement type: