CoolFace
Datasetpublic

timlawrenz/gnn-ruby-code-study

GNN Ruby Code Study Systematic study of Graph Neural Network architectures for Ruby code complexity prediction and generation. Paper: Graph Neural Networks for Ruby Code Complexity Prediction and Generation: A Systematic Architecture Study Dataset 22,452 Ruby methods parsed into AST graphs with 74-dimensional node features. Split Samples File Train 19,084 dataset/train.jsonl Validation 3,368 dataset/val.jsonl Each JSONL record contains:… See the full description on the dataset page: https://huggingface.co/datasets/timlawrenz/gnn-ruby-code-study.

sourceHugging Facemitupdated 5mo agoView on Hugging Face
0likes60downloads
run_topology_arm.sh171 linesDownload Raw Back to scripts
1#!/usr/bin/env bash2# Runner script for Track 4: Decoder Topology experiments.3# Tests tree-aware decoding (teacher_forced / iterative) vs chain baseline.4# Outputs METRICS:{json} for Ratiocinator fleet parsing.5#6# Environment variables (set by Ratiocinator fleet):7#   DECODER_EDGE_MODE - chain, teacher_forced, iterative (default: teacher_forced)8#   DECODER_CONV_TYPE - GCN, SAGE, GAT, GIN, GraphConv (default: GAT)9#   HIDDEN_DIM        - Hidden dimension (default: 256)10#   NUM_LAYERS        - Number of decoder layers (default: 5)11#   LEARNING_RATE     - Learning rate (default: 0.001)12#   TYPE_WEIGHT       - Weight for node type loss (default: 2.0)13#   PARENT_WEIGHT     - Weight for parent prediction loss (default: 1.0)14#   LOSS_FN           - Loss function: improved, comprehensive, simple, original (default: improved)15#   EPOCHS            - Training epochs (default: 30)16#   DATASET_PATH      - Path to dataset dir (default: dataset/)17 18set -uo pipefail19 20DECODER_EDGE_MODE="${DECODER_EDGE_MODE:-teacher_forced}"21DECODER_CONV_TYPE="${DECODER_CONV_TYPE:-GAT}"22HIDDEN_DIM="${HIDDEN_DIM:-256}"23NUM_LAYERS="${NUM_LAYERS:-5}"24LEARNING_RATE="${LEARNING_RATE:-0.001}"25TYPE_WEIGHT="${TYPE_WEIGHT:-2.0}"26PARENT_WEIGHT="${PARENT_WEIGHT:-1.0}"27LOSS_FN="${LOSS_FN:-improved}"28EPOCHS="${EPOCHS:-30}"29DATASET_PATH="${DATASET_PATH:-dataset/}"30OUTPUT_PATH="models/experiment_topology_decoder.pt"31ENCODER_PATH="models/best_model.pt"32 33echo "=== Track 4: Decoder Topology Arm ==="34echo "EDGE_MODE=$DECODER_EDGE_MODE DECODER=$DECODER_CONV_TYPE HIDDEN=$HIDDEN_DIM LAYERS=$NUM_LAYERS"35echo "LR=$LEARNING_RATE TYPE_W=$TYPE_WEIGHT PARENT_W=$PARENT_WEIGHT LOSS=$LOSS_FN"36 37# Pull LFS files if they are pointers (e.g., after shallow clone)38if command -v git-lfs &>/dev/null || git lfs version &>/dev/null 2>&1; then39    echo "Pulling LFS files..."40    git lfs pull 2>&1 || echo "LFS pull returned non-zero (may be OK if files exist)"41elif [ -f "${DATASET_PATH}/validation.jsonl" ] && head -1 "${DATASET_PATH}/validation.jsonl" | grep -q "^version https://git-lfs"; then42    echo "ERROR: LFS pointer files detected but git-lfs not installed"43    exit 144fi45 46# Ensure train/val split exists47if [ ! -f "${DATASET_PATH}/train.jsonl" ]; then48    echo "Creating train/val split..."49    python scripts/split_complexity_data.py \50        --input "${DATASET_PATH}/validation.jsonl" \51        --output-dir "${DATASET_PATH}"52fi53 54# Symlink validation.jsonl → val.jsonl for compatibility55if [ -f "${DATASET_PATH}/val.jsonl" ]; then56    ORIG_VAL="${DATASET_PATH}/validation.jsonl"57    if [ -f "$ORIG_VAL" ] && ! [ -L "$ORIG_VAL" ]; then58        mv "$ORIG_VAL" "${DATASET_PATH}/validation_full.jsonl"59    fi60    ln -sf val.jsonl "${DATASET_PATH}/validation.jsonl"61fi62 63# Need pre-trained encoder64if [ ! -f "$ENCODER_PATH" ]; then65    echo "Training encoder first..."66    python train.py --epochs 20 --output_path "$ENCODER_PATH" --dataset_path "$DATASET_PATH" --num_workers 067fi68 69mkdir -p models70 71# Run autoencoder training with tree-aware decoder — stream output72TRAIN_LOG="/tmp/topo_train_$$.log"73python train_autoencoder.py \74    --dataset_path "$DATASET_PATH" \75    --epochs "$EPOCHS" \76    --output_path "$OUTPUT_PATH" \77    --encoder_weights_path "$ENCODER_PATH" \78    --hidden_dim "$HIDDEN_DIM" \79    --num_layers "$NUM_LAYERS" \80    --decoder_conv_type "$DECODER_CONV_TYPE" \81    --decoder_edge_mode "$DECODER_EDGE_MODE" \82    --learning_rate "$LEARNING_RATE" \83    --type_weight "$TYPE_WEIGHT" \84    --parent_weight "$PARENT_WEIGHT" \85    --loss_fn "$LOSS_FN" \86    2>&1 | tee "$TRAIN_LOG"87 88TRAIN_RC=${PIPESTATUS[0]}89if [ "$TRAIN_RC" -ne 0 ]; then90    echo "ERROR: train_autoencoder.py exited with code $TRAIN_RC"91    echo "METRICS:{\"error\": \"training_failed\", \"exit_code\": $TRAIN_RC}"92    exit 193fi94 95BEST_VAL_LOSS=$(grep "Best validation loss" "$TRAIN_LOG" | grep -oP '[\d.]+' | tail -1)96 97# Run syntactic validity evaluation98python -c "99import sys, os, json, torch100sys.path.insert(0, os.path.join(os.path.dirname('.'), 'src'))101from models import ASTAutoencoder102from data_processing import create_data_loaders103 104device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')105num_samples = 100106valid_count = 0107total = 0108 109try:110    model = ASTAutoencoder(111        encoder_input_dim=74,112        node_output_dim=74,113        hidden_dim=$HIDDEN_DIM,114        num_layers=$NUM_LAYERS,115        conv_type='SAGE',116        freeze_encoder=True,117        encoder_weights_path='$ENCODER_PATH',118        decoder_conv_type='$DECODER_CONV_TYPE',119        decoder_edge_mode='$DECODER_EDGE_MODE',120    ).to(device)121 122    checkpoint = torch.load('$OUTPUT_PATH', map_location=device, weights_only=False)123    model.decoder.load_state_dict(checkpoint['decoder_state_dict'])124    model.eval()125 126    # Load val data127    val_path = os.path.join('${DATASET_PATH}', 'val.jsonl')128    if not os.path.exists(val_path):129        val_path = os.path.join('${DATASET_PATH}', 'validation.jsonl')130    _, val_loader = create_data_loaders(val_path, val_path, batch_size=1, shuffle=False, num_workers=0)131 132    with torch.no_grad():133        for batch in val_loader:134            if total >= num_samples:135                break136            batch = batch.to(device)137            result = model(batch)138            recon = result['reconstruction']139            node_feats = recon.get('node_features') if isinstance(recon, dict) else None140            if node_feats is not None:141                pred_types = node_feats.argmax(dim=-1)142                unique_types = len(pred_types.unique())143                if unique_types > 2:144                    valid_count += 1145            total += 1146 147    validity_pct = (valid_count / total * 100) if total > 0 else 0.0148except Exception as e:149    validity_pct = 0.0150    total = num_samples151    print(f'Eval error: {e}', file=sys.stderr)152 153print('METRICS:' + json.dumps({154    'syntactic_validity_pct': round(validity_pct, 2),155    'val_loss': round(float('${BEST_VAL_LOSS:-0}'), 4),156    'samples_evaluated': total,157    'valid_samples': valid_count,158    'decoder_edge_mode': '$DECODER_EDGE_MODE',159    'decoder_conv_type': '$DECODER_CONV_TYPE',160    'hidden_dim': $HIDDEN_DIM,161    'num_layers': $NUM_LAYERS,162    'loss_fn': '$LOSS_FN',163    'type_weight': $TYPE_WEIGHT,164    'parent_weight': $PARENT_WEIGHT,165    'learning_rate': $LEARNING_RATE,166    'epochs': $EPOCHS,167}))168" 2>&1169 170rm -f "$TRAIN_LOG"171