Tabular Classification
Transformers
Safetensors
felatab
feature-extraction
fela
tabular
in-context-learning
prior-fitted-network
foundation-model
delta-rule
cpu
on-device
custom_code
Eval Results (legacy)
Instructions to use lowdown-labs/fela-tab with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use lowdown-labs/fela-tab with Transformers:
# Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("lowdown-labs/fela-tab", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
fleet: spot/restore/checkpoint + systemd self-heal (launch_ec2.py)
Browse files- benchmark/tabarena/launch_ec2.py +191 -0
benchmark/tabarena/launch_ec2.py
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Launch the FelaTab x TabArena benchmark on EC2 (replaces the unreliable HF Jobs path).
|
| 2 |
+
|
| 3 |
+
Pushes the current benchmark scripts to the HF model repo, then boots an on-demand
|
| 4 |
+
c7i.8xlarge (32 vCPU / 64 GiB, ~$1.43/hr in us-west-2) whose user-data runs
|
| 5 |
+
ec2_run.sh: lite shakedown -> (guard) -> full suite -> upload artifacts to
|
| 6 |
+
lowdown-labs/fela-tab-tabarena-results -> poweroff (shutdown behavior = terminate).
|
| 7 |
+
|
| 8 |
+
Prereqs: `aws login` (SSO session), HF_TOKEN in env (write token for lowdown-labs).
|
| 9 |
+
|
| 10 |
+
Usage:
|
| 11 |
+
HF_TOKEN=hf_... python launch_ec2.py # lite shakedown then full
|
| 12 |
+
HF_TOKEN=hf_... python launch_ec2.py --phases lite # shakedown only
|
| 13 |
+
HF_TOKEN=hf_... python launch_ec2.py --phases full --datasets "houses,diamonds,..." # shard
|
| 14 |
+
|
| 15 |
+
Note: HF_TOKEN is embedded in EC2 user-data (visible to anyone with
|
| 16 |
+
DescribeInstanceAttribute permission on this account). Rotate the token after the run
|
| 17 |
+
if that matters to you.
|
| 18 |
+
"""
|
| 19 |
+
|
| 20 |
+
import argparse
|
| 21 |
+
import os
|
| 22 |
+
import time
|
| 23 |
+
import urllib.request
|
| 24 |
+
|
| 25 |
+
import boto3
|
| 26 |
+
from huggingface_hub import HfApi, get_token
|
| 27 |
+
|
| 28 |
+
MODEL_REPO = "lowdown-labs/fela-tab"
|
| 29 |
+
INSTANCE_TYPE = "c7i.8xlarge"
|
| 30 |
+
KEY_NAME = "felatab-tabarena"
|
| 31 |
+
SG_NAME = "felatab-tabarena-ssh"
|
| 32 |
+
AMI_PARAM = "/aws/service/canonical/ubuntu/server/24.04/stable/current/amd64/hvm/ebs-gp3/ami-id"
|
| 33 |
+
|
| 34 |
+
USER_DATA_TMPL = """#!/bin/bash
|
| 35 |
+
set -euxo pipefail
|
| 36 |
+
export HOME=/root
|
| 37 |
+
export DEBIAN_FRONTEND=noninteractive
|
| 38 |
+
apt-get update -qq
|
| 39 |
+
apt-get install -y -qq git curl python3 python3-venv
|
| 40 |
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
| 41 |
+
export PATH="$HOME/.local/bin:$PATH"
|
| 42 |
+
uv venv --seed /work-bootvenv
|
| 43 |
+
uv pip install --python /work-bootvenv/bin/python -q huggingface_hub
|
| 44 |
+
mkdir -p /work
|
| 45 |
+
export HF_TOKEN="{hf_token}"
|
| 46 |
+
/work-bootvenv/bin/python -c "from huggingface_hub import snapshot_download; snapshot_download('{model_repo}', allow_patterns=['benchmark/tabarena/ec2_run.sh'], local_dir='/work/fela-tab')"
|
| 47 |
+
cat > /etc/felatab.env <<EOF
|
| 48 |
+
HF_TOKEN={hf_token}
|
| 49 |
+
PHASES={phases}
|
| 50 |
+
RUN_NAME={run_name}
|
| 51 |
+
DATASETS={datasets}
|
| 52 |
+
WITH_LGBM={with_lgbm}
|
| 53 |
+
SELF_TERMINATE=1
|
| 54 |
+
CHECKPOINT={checkpoint}
|
| 55 |
+
RESTORE={restore}
|
| 56 |
+
EOF
|
| 57 |
+
chmod 600 /etc/felatab.env
|
| 58 |
+
cat > /etc/systemd/system/felatab-benchmark.service <<'EOF'
|
| 59 |
+
[Unit]
|
| 60 |
+
Description=FelaTab TabArena benchmark
|
| 61 |
+
After=network-online.target
|
| 62 |
+
Wants=network-online.target
|
| 63 |
+
|
| 64 |
+
[Service]
|
| 65 |
+
Type=simple
|
| 66 |
+
EnvironmentFile=/etc/felatab.env
|
| 67 |
+
ExecStart=/bin/bash /work/fela-tab/benchmark/tabarena/ec2_run.sh
|
| 68 |
+
User=root
|
| 69 |
+
StandardOutput=append:/work/logs_boot.log
|
| 70 |
+
StandardError=append:/work/logs_boot.log
|
| 71 |
+
|
| 72 |
+
[Install]
|
| 73 |
+
WantedBy=multi-user.target
|
| 74 |
+
EOF
|
| 75 |
+
systemctl daemon-reload
|
| 76 |
+
systemctl enable --now felatab-benchmark.service
|
| 77 |
+
"""
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
def ensure_key_pair(ec2, key_path):
|
| 81 |
+
names = {k["KeyName"] for k in ec2.describe_key_pairs()["KeyPairs"]}
|
| 82 |
+
if KEY_NAME in names:
|
| 83 |
+
print(f"key pair {KEY_NAME} exists")
|
| 84 |
+
return
|
| 85 |
+
kp = ec2.create_key_pair(KeyName=KEY_NAME)
|
| 86 |
+
with open(key_path, "w") as f:
|
| 87 |
+
f.write(kp["KeyMaterial"])
|
| 88 |
+
os.chmod(key_path, 0o400)
|
| 89 |
+
print(f"created key pair {KEY_NAME} -> {key_path}")
|
| 90 |
+
|
| 91 |
+
|
| 92 |
+
def ensure_security_group(ec2):
|
| 93 |
+
vpcs = ec2.describe_vpcs(Filters=[{"Name": "isDefault", "Values": ["true"]}])["Vpcs"]
|
| 94 |
+
vpc_id = vpcs[0]["VpcId"]
|
| 95 |
+
for sg in ec2.describe_security_groups(
|
| 96 |
+
Filters=[{"Name": "group-name", "Values": [SG_NAME]}, {"Name": "vpc-id", "Values": [vpc_id]}]
|
| 97 |
+
)["SecurityGroups"]:
|
| 98 |
+
print(f"security group {SG_NAME} exists ({sg['GroupId']})")
|
| 99 |
+
return sg["GroupId"]
|
| 100 |
+
my_ip = urllib.request.urlopen("https://checkip.amazonaws.com").read().decode().strip()
|
| 101 |
+
sg = ec2.create_security_group(GroupName=SG_NAME, Description="FelaTab TabArena runner (ssh)", VpcId=vpc_id)
|
| 102 |
+
ec2.authorize_security_group_ingress(
|
| 103 |
+
GroupId=sg["GroupId"],
|
| 104 |
+
IpPermissions=[{"IpProtocol": "tcp", "FromPort": 22, "ToPort": 22,
|
| 105 |
+
"IpRanges": [{"CidrIp": f"{my_ip}/32", "Description": "launcher ip"}]}],
|
| 106 |
+
)
|
| 107 |
+
print(f"created security group {SG_NAME} ({sg['GroupId']}), ssh from {my_ip}/32")
|
| 108 |
+
return sg["GroupId"]
|
| 109 |
+
|
| 110 |
+
|
| 111 |
+
def main():
|
| 112 |
+
ap = argparse.ArgumentParser()
|
| 113 |
+
ap.add_argument("--phases", default="lite,full", help="comma list: lite,full or just lite / full")
|
| 114 |
+
ap.add_argument("--datasets", default="", help="optional csv shard (full mode only)")
|
| 115 |
+
ap.add_argument("--run-name", default="felatab_ec2")
|
| 116 |
+
ap.add_argument("--instance-type", default=INSTANCE_TYPE)
|
| 117 |
+
ap.add_argument("--with-lgbm", default="0")
|
| 118 |
+
ap.add_argument("--spot", action="store_true",
|
| 119 |
+
help="persistent spot with stop-on-interruption: EBS cache survives, "
|
| 120 |
+
"systemd service resumes the run on restart")
|
| 121 |
+
ap.add_argument("--checkpoint", default="0", choices=["0", "1"],
|
| 122 |
+
help="upload results cache to the HF repo every 30 min")
|
| 123 |
+
ap.add_argument("--restore", default="0", choices=["0", "1"],
|
| 124 |
+
help="download existing raw/<run-name> cache before running")
|
| 125 |
+
args = ap.parse_args()
|
| 126 |
+
|
| 127 |
+
token = os.environ.get("HF_TOKEN") or get_token()
|
| 128 |
+
assert token, "need HF_TOKEN in env or a logged-in `hf auth login` session"
|
| 129 |
+
api = HfApi(token=token)
|
| 130 |
+
|
| 131 |
+
here = os.path.dirname(os.path.abspath(__file__))
|
| 132 |
+
for fname in ("ec2_run.sh", "run_tabarena.py", "fela_ag_model.py"):
|
| 133 |
+
api.upload_file(
|
| 134 |
+
path_or_fileobj=os.path.join(here, fname),
|
| 135 |
+
path_in_repo=f"benchmark/tabarena/{fname}",
|
| 136 |
+
repo_id=MODEL_REPO, repo_type="model",
|
| 137 |
+
commit_message=f"Update TabArena EC2 runner scripts ({fname})",
|
| 138 |
+
)
|
| 139 |
+
print(f"uploaded {fname} -> {MODEL_REPO}")
|
| 140 |
+
|
| 141 |
+
ec2 = boto3.client("ec2")
|
| 142 |
+
ssm = boto3.client("ssm")
|
| 143 |
+
ami = ssm.get_parameter(Name=AMI_PARAM)["Parameter"]["Value"]
|
| 144 |
+
print(f"AMI: {ami}")
|
| 145 |
+
|
| 146 |
+
key_path = os.path.expanduser(f"~/.aws/{KEY_NAME}.pem")
|
| 147 |
+
ensure_key_pair(ec2, key_path)
|
| 148 |
+
sg_id = ensure_security_group(ec2)
|
| 149 |
+
|
| 150 |
+
user_data = USER_DATA_TMPL.format(
|
| 151 |
+
hf_token=token, model_repo=MODEL_REPO, phases=args.phases,
|
| 152 |
+
run_name=args.run_name, datasets=args.datasets, with_lgbm=args.with_lgbm,
|
| 153 |
+
checkpoint=args.checkpoint, restore=args.restore,
|
| 154 |
+
)
|
| 155 |
+
kwargs = dict(
|
| 156 |
+
ImageId=ami,
|
| 157 |
+
InstanceType=args.instance_type,
|
| 158 |
+
KeyName=KEY_NAME,
|
| 159 |
+
MinCount=1, MaxCount=1,
|
| 160 |
+
NetworkInterfaces=[{"DeviceIndex": 0, "Groups": [sg_id], "AssociatePublicIpAddress": True}],
|
| 161 |
+
BlockDeviceMappings=[{"DeviceName": "/dev/sda1",
|
| 162 |
+
"Ebs": {"VolumeSize": 200, "VolumeType": "gp3", "DeleteOnTermination": True}}],
|
| 163 |
+
TagSpecifications=[{"ResourceType": "instance",
|
| 164 |
+
"Tags": [{"Key": "Name", "Value": f"felatab-tabarena-{args.run_name}"}]}],
|
| 165 |
+
UserData=user_data,
|
| 166 |
+
)
|
| 167 |
+
if args.spot:
|
| 168 |
+
# persistent spot, stop (not terminate) on interruption: the EBS results cache
|
| 169 |
+
# survives and the systemd service resumes the run when capacity returns
|
| 170 |
+
kwargs["InstanceMarketOptions"] = {
|
| 171 |
+
"MarketType": "spot",
|
| 172 |
+
"SpotOptions": {"SpotInstanceType": "persistent", "InstanceInterruptionBehavior": "stop"},
|
| 173 |
+
}
|
| 174 |
+
kwargs["InstanceInitiatedShutdownBehavior"] = "stop"
|
| 175 |
+
else:
|
| 176 |
+
kwargs["InstanceInitiatedShutdownBehavior"] = "terminate"
|
| 177 |
+
resp = ec2.run_instances(**kwargs)
|
| 178 |
+
iid = resp["Instances"][0]["InstanceId"]
|
| 179 |
+
print(f"instance: {iid} ({args.instance_type}, phases={args.phases}, run={args.run_name})")
|
| 180 |
+
|
| 181 |
+
ec2.get_waiter("instance_running").wait(InstanceIds=[iid])
|
| 182 |
+
desc = ec2.describe_instances(InstanceIds=[iid])["Reservations"][0]["Instances"][0]
|
| 183 |
+
ip = desc.get("PublicIpAddress", "<no public ip>")
|
| 184 |
+
print(f"running at {ip}")
|
| 185 |
+
print(f"watch: ssh -i {key_path} ubuntu@{ip} 'tail -f /work/logs_boot.log'")
|
| 186 |
+
print(f"status: aws ec2 describe-instances --instance-ids {iid} --query 'Reservations[0].Instances[0].State.Name'")
|
| 187 |
+
print("artifacts land in https://huggingface.co/datasets/lowdown-labs/fela-tab-tabarena-results")
|
| 188 |
+
|
| 189 |
+
|
| 190 |
+
if __name__ == "__main__":
|
| 191 |
+
main()
|